diff options
Diffstat (limited to 'docs/source')
223 files changed, 21116 insertions, 0 deletions
diff --git a/docs/source/_static/.gitignore b/docs/source/_static/.gitignore new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/docs/source/_static/.gitignore diff --git a/docs/source/_static/breathe.css b/docs/source/_static/breathe.css new file mode 100644 index 0000000..d86028c --- /dev/null +++ b/docs/source/_static/breathe.css @@ -0,0 +1 @@ +/* This is a dummy css file to prevent 404 errors */ diff --git a/docs/source/_static/img/blinky-to-flash.png b/docs/source/_static/img/blinky-to-flash.png Binary files differnew file mode 100644 index 0000000..0320c5b --- /dev/null +++ b/docs/source/_static/img/blinky-to-flash.png diff --git a/docs/source/_static/img/blinky.png b/docs/source/_static/img/blinky.png Binary files differnew file mode 100644 index 0000000..bda4cee --- /dev/null +++ b/docs/source/_static/img/blinky.png diff --git a/docs/source/_static/img/button-new.png b/docs/source/_static/img/button-new.png Binary files differnew file mode 100644 index 0000000..3fd98be --- /dev/null +++ b/docs/source/_static/img/button-new.png diff --git a/docs/source/_static/img/button-open.png b/docs/source/_static/img/button-open.png Binary files differnew file mode 100644 index 0000000..466fc10 --- /dev/null +++ b/docs/source/_static/img/button-open.png diff --git a/docs/source/_static/img/button-save.png b/docs/source/_static/img/button-save.png Binary files differnew file mode 100644 index 0000000..7eba286 --- /dev/null +++ b/docs/source/_static/img/button-save.png diff --git a/docs/source/_static/img/button-serial-monitor.png b/docs/source/_static/img/button-serial-monitor.png Binary files differnew file mode 100644 index 0000000..aec9741 --- /dev/null +++ b/docs/source/_static/img/button-serial-monitor.png diff --git a/docs/source/_static/img/button-stop.png b/docs/source/_static/img/button-stop.png Binary files differnew file mode 100644 index 0000000..4812ae9 --- /dev/null +++ b/docs/source/_static/img/button-stop.png diff --git a/docs/source/_static/img/button-upload.png b/docs/source/_static/img/button-upload.png Binary files differnew file mode 100644 index 0000000..0f41eeb --- /dev/null +++ b/docs/source/_static/img/button-upload.png diff --git a/docs/source/_static/img/button-verify.png b/docs/source/_static/img/button-verify.png Binary files differnew file mode 100644 index 0000000..95abeb8 --- /dev/null +++ b/docs/source/_static/img/button-verify.png diff --git a/docs/source/_static/img/codeblocks_build.png b/docs/source/_static/img/codeblocks_build.png Binary files differnew file mode 100644 index 0000000..c98bcdc --- /dev/null +++ b/docs/source/_static/img/codeblocks_build.png diff --git a/docs/source/_static/img/codeblocks_makefile.png b/docs/source/_static/img/codeblocks_makefile.png Binary files differnew file mode 100644 index 0000000..a0ef21f --- /dev/null +++ b/docs/source/_static/img/codeblocks_makefile.png diff --git a/docs/source/_static/img/codeblocks_maketargets.png b/docs/source/_static/img/codeblocks_maketargets.png Binary files differnew file mode 100644 index 0000000..bbb68cb --- /dev/null +++ b/docs/source/_static/img/codeblocks_maketargets.png diff --git a/docs/source/_static/img/codeblocks_newproject.png b/docs/source/_static/img/codeblocks_newproject.png Binary files differnew file mode 100644 index 0000000..8d08d1f --- /dev/null +++ b/docs/source/_static/img/codeblocks_newproject.png diff --git a/docs/source/_static/img/github-clone-in-windows.png b/docs/source/_static/img/github-clone-in-windows.png Binary files differnew file mode 100644 index 0000000..41d76d1 --- /dev/null +++ b/docs/source/_static/img/github-clone-in-windows.png diff --git a/docs/source/_static/img/ide-blinky.png b/docs/source/_static/img/ide-blinky.png Binary files differnew file mode 100644 index 0000000..3cccdb4 --- /dev/null +++ b/docs/source/_static/img/ide-blinky.png diff --git a/docs/source/_static/img/jtag-wiring.png b/docs/source/_static/img/jtag-wiring.png Binary files differnew file mode 100644 index 0000000..8f31f99 --- /dev/null +++ b/docs/source/_static/img/jtag-wiring.png diff --git a/docs/source/_static/img/osx-network-prefs-unconfigured.png b/docs/source/_static/img/osx-network-prefs-unconfigured.png Binary files differnew file mode 100644 index 0000000..70d2fa0 --- /dev/null +++ b/docs/source/_static/img/osx-network-prefs-unconfigured.png diff --git a/docs/source/_static/img/osx-unconfigured-popup.png b/docs/source/_static/img/osx-unconfigured-popup.png Binary files differnew file mode 100644 index 0000000..a43ad57 --- /dev/null +++ b/docs/source/_static/img/osx-unconfigured-popup.png diff --git a/docs/source/_static/img/round_logo_32x32.ico b/docs/source/_static/img/round_logo_32x32.ico Binary files differnew file mode 100644 index 0000000..29fb2bf --- /dev/null +++ b/docs/source/_static/img/round_logo_32x32.ico diff --git a/docs/source/_static/img/round_logo_60x60.png b/docs/source/_static/img/round_logo_60x60.png Binary files differnew file mode 100644 index 0000000..dacd36a --- /dev/null +++ b/docs/source/_static/img/round_logo_60x60.png diff --git a/docs/source/_static/img/serial-monitor.png b/docs/source/_static/img/serial-monitor.png Binary files differnew file mode 100644 index 0000000..6162dab --- /dev/null +++ b/docs/source/_static/img/serial-monitor.png diff --git a/docs/source/_static/img/serial-port-mac.png b/docs/source/_static/img/serial-port-mac.png Binary files differnew file mode 100644 index 0000000..b3a1989 --- /dev/null +++ b/docs/source/_static/img/serial-port-mac.png diff --git a/docs/source/_static/img/serial-port-ubuntu.png b/docs/source/_static/img/serial-port-ubuntu.png Binary files differnew file mode 100644 index 0000000..8038e41 --- /dev/null +++ b/docs/source/_static/img/serial-port-ubuntu.png diff --git a/docs/source/_static/img/serial-port-win.png b/docs/source/_static/img/serial-port-win.png Binary files differnew file mode 100644 index 0000000..90dc1c4 --- /dev/null +++ b/docs/source/_static/img/serial-port-win.png diff --git a/docs/source/_static/img/upload-button.png b/docs/source/_static/img/upload-button.png Binary files differnew file mode 100644 index 0000000..20a663f --- /dev/null +++ b/docs/source/_static/img/upload-button.png diff --git a/docs/source/_static/img/verify-success.png b/docs/source/_static/img/verify-success.png Binary files differnew file mode 100644 index 0000000..6928674 --- /dev/null +++ b/docs/source/_static/img/verify-success.png diff --git a/docs/source/_static/img/verify_button.png b/docs/source/_static/img/verify_button.png Binary files differnew file mode 100644 index 0000000..37100db --- /dev/null +++ b/docs/source/_static/img/verify_button.png diff --git a/docs/source/_static/img/win7-copy-arm-bin-address.png b/docs/source/_static/img/win7-copy-arm-bin-address.png Binary files differnew file mode 100644 index 0000000..a3886d1 --- /dev/null +++ b/docs/source/_static/img/win7-copy-arm-bin-address.png diff --git a/docs/source/_static/img/win7-copy-python-address.png b/docs/source/_static/img/win7-copy-python-address.png Binary files differnew file mode 100644 index 0000000..34d3022 --- /dev/null +++ b/docs/source/_static/img/win7-copy-python-address.png diff --git a/docs/source/_static/img/win7-github-open-in-explorer.png b/docs/source/_static/img/win7-github-open-in-explorer.png Binary files differnew file mode 100644 index 0000000..8320a90 --- /dev/null +++ b/docs/source/_static/img/win7-github-open-in-explorer.png diff --git a/docs/source/_static/img/win7-python-arm-bin-path.png b/docs/source/_static/img/win7-python-arm-bin-path.png Binary files differnew file mode 100644 index 0000000..8dcc8ed --- /dev/null +++ b/docs/source/_static/img/win7-python-arm-bin-path.png diff --git a/docs/source/_static/img/win7-python-path.png b/docs/source/_static/img/win7-python-path.png Binary files differnew file mode 100644 index 0000000..8898a9e --- /dev/null +++ b/docs/source/_static/img/win7-python-path.png diff --git a/docs/source/_static/img/win7-python-prompt.png b/docs/source/_static/img/win7-python-prompt.png Binary files differnew file mode 100644 index 0000000..27ae62a --- /dev/null +++ b/docs/source/_static/img/win7-python-prompt.png diff --git a/docs/source/_static/index-style.css b/docs/source/_static/index-style.css new file mode 100644 index 0000000..d7c42b3 --- /dev/null +++ b/docs/source/_static/index-style.css @@ -0,0 +1,19 @@ +/* Contents style */ + +.contents-table { + font-size: large; +} + +.contents-table ul, .contents-table li { + display: inline; +} + +.contents-table td { + padding: 0em 1em 0em; +} + +.contents-table ul { + list-style-type: none; + margin: 0em; + padding-left: 0px; +} diff --git a/docs/source/_static/leaflabs-docs.css b/docs/source/_static/leaflabs-docs.css new file mode 100644 index 0000000..18f5bcc --- /dev/null +++ b/docs/source/_static/leaflabs-docs.css @@ -0,0 +1 @@ +/* Any custom CSS you want applied goes here */ diff --git a/docs/source/_templates/.gitignore b/docs/source/_templates/.gitignore new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/docs/source/_templates/.gitignore diff --git a/docs/source/_templates/indexcontent.html b/docs/source/_templates/indexcontent.html new file mode 100644 index 0000000..a043f8a --- /dev/null +++ b/docs/source/_templates/indexcontent.html @@ -0,0 +1,117 @@ +{# This file generates the top-level index.html file. We are very + obviously stealing from the Python docs' style ;). +#} + +<!-- Extend our layout.html. So inheritance hierarchy is Sphinx's + layout, then our layout.html, then this file. --> +{% extends "layout.html" %} + +<!-- Pull in extra index stylesheet --> +{% set css_files = css_files + ["_static/index-style.css"] %} + +<!-- Separator for contents lists --> +{% set content_sep = "·" %} + +<!-- Content --> +{% block body %} +<h1>Hi!</h1> + +This is the documentation for the LeafLabs Maple boards, version {{ +release }}. + +<h2>Read This First</h2> + +<p>Just getting started? Try the <a href="{{ +pathto("maple-quickstart") }}">Quickstart</a>. Having problems? Check +out <a href="{{ pathto("troubleshooting") }}">Troubleshooting</a> and +the <a href="{{ pathto("faq") }}">FAQ</a>. Can't find what you want +here? Look on the <a href="http://wiki.leaflabs.com/">LeafLabs +wiki</a>. +</p> + +<p>See the <a href="{{ pathto("whats-new") }}">What's New</a> page for +changes that are new in {{ release }}.</p> + +<h2>Contents at a Glance</h2> + +<table class="contents-table"> + <tr> + <td><p><strong>Getting Started</strong></p> + <ul> + <li><a href="{{ pathto("maple-quickstart") }}">Quickstart</a> + {{ content_sep }}</li> + <li><a href="{{ pathto("maple-ide-install") }}">Installing Maple IDE</a> + {{ content_sep }}</li> + <li><a href="{{ pathto("ide") }}">Using Maple IDE</a> + {{ content_sep }}</li> + <li><a href="{{ pathto("unix-toolchain") }}">Command-Line + Toolchain</a></li> + </ul> + </td> + <td><p><strong>Boards</strong></p> + <ul> + <li><a href="{{ pathto("hardware/maple") }}">Maple</a> + {{ content_sep }}</li> + <li><a href="{{ pathto("hardware/maple-ret6") }}">Maple RET6 Edition</a> + {{ content_sep }}</li> + <li><a href="{{ pathto("hardware/maple-mini") }}">Maple Mini</a> + {{ content_sep }}</li> + <li><a href="{{ pathto("hardware/maple-native-beta") }}">Maple + Native β</a></li> + </ul> + </td> + </tr> + <tr> + <td><p><strong>Programming</strong></p> + <ul> + <li><a href="{{ pathto("language") }}">Language Reference</a> + {{ content_sep }}</li> + <li><a href="{{ pathto("troubleshooting") }}">Troubleshooting</a> + {{ content_sep }}</li> + <li><a href="{{ pathto("faq") }}">FAQ</a> + {{ content_sep }}</li> + <li><a href="{{ pathto("libraries") }}">Libraries</a> + {{ content_sep }}</li> + <li><a href="{{ pathto("libmaple") }}"><tt>libmaple</tt></a> + {{ content_sep }}</li> + <li><a href="{{ pathto("bootloader") }}">Bootloader</a> + {{ content_sep }}</li> + <li><a href="{{ pathto("arm-gcc") }}">GCC and libc</a> + {{ content_sep }}</li> + <li><a href="{{ pathto("arduino-compatibility") }}">Arduino + Compatibility</a></li> + </ul> + </td> + <td><p><strong>Hardware and Peripherals</strong></p> + <ul> + <li><a href="{{ pathto("stm32") }}">STM32</a> + {{ content_sep }}</li> + <li><a href="{{ pathto("adc") }}">ADC</a> + {{ content_sep }}</li> + <li><a href="{{ pathto("external-interrupts") }}">External + Interrupts</a> {{ content_sep }}</li> + <li><a href="{{ pathto("fsmc") }}">FSMC</a> + {{ content_sep }}</li> + <li><a href="{{ pathto("gpio") }}">GPIO</a> + {{ content_sep }}</li> + <li><a href="{{ pathto("i2c") }}">I<sup>2</sup>C</a> + {{ content_sep }}</li> + <li><a href="{{ pathto("jtag") }}">JTAG</a> + {{ content_sep }}</li> + <li><a href="{{ pathto("pwm") }}">PWM</a> + {{ content_sep }}</li> + <li><a href="{{ pathto("spi") }}">SPI</a> + {{ content_sep }}</li> + <li><a href="{{ pathto("systick") }}">SysTick</a> + {{ content_sep }}</li> + <li><a href="{{ pathto("timers") }}">Timers</a> + {{ content_sep }}</li> + <li><a href="{{ pathto("usart") }}">USART</a> + {{ content_sep }}</li> + <li><a href="{{ pathto("usb") }}">USB</a></li> + </ul> + </td> + </tr> +</table> + +{% endblock %} diff --git a/docs/source/_templates/layout.html b/docs/source/_templates/layout.html new file mode 100644 index 0000000..2fd81ce --- /dev/null +++ b/docs/source/_templates/layout.html @@ -0,0 +1,11 @@ +{% extends "!layout.html" %} + +{% set css_files = css_files + ["_static/leaflabs-docs.css"] %} + +{% block rootrellink %} + <li><a href="http://leaflabs.com/"> + <img width="16px" src="_static/img/round_logo_32x32.ico"></img> + leaflabs.com + </a>·</li> + <li><a href="{{ pathto('index') }}">{{ shorttitle }}</a>{{ reldelim1 }}</li> +{% endblock %} diff --git a/docs/source/adc.rst b/docs/source/adc.rst new file mode 100644 index 0000000..937b178 --- /dev/null +++ b/docs/source/adc.rst @@ -0,0 +1,104 @@ +.. _adc: + +===== + ADC +===== + +Analog to digital conversion is the process of reading a physical +voltage as a number. Maple can convert voltages between 0 and 3.3V to +numbers between 0 and 4095. + +.. contents:: Contents + :local: + +ADC On Maple +------------ + +Doing analog-to-digital conversion on the Maple is simple. +:ref:`Maple IDE <ide>` contains a basic example. To see it, choose +Analog > AnalogInSerial from the :ref:`examples menu <ide-examples>`. + +In order to set up your board for conversion, first connect the wire +(potentiometer, etc.) with the voltage you want to measure to a +:ref:`pin <gpio>` which can perform ADC. Each pin which can do ADC +has "AIN" (or "ain") written next to the the pin number. Then, as in +the example program, set the chosen pin's :ref:`pin mode +<lang-pinmode>` to ``INPUT_ANALOG`` by calling ``pinMode(<your_pin>, +INPUT_ANALOG)``. You will usually do this in your :ref:`lang-setup` +function. Now you can use :ref:`lang-analogread` to perform an ADC +reading. + +.. _adc-function-reference: + +Function Reference +------------------ + +* :ref:`lang-analogread` +* :ref:`lang-pinmode` +* :ref:`libmaple-adc` (low-level ADC support) + +.. _adc-noise-bias: + +Noise and Bias +-------------- + +Maple has a large number of pins which are capable of taking 12-bit +ADC measurements, which means that voltages from 0 to 3.3V are read as +numbers from 0 to 4095. In theory, this means that a change in +voltage of about 1 millivolt should change the numeric voltage reading +by 1. In reality, however, a number of issues introduce noise and +bias into this reading, and a number of techniques must be used to get +good precision and accuracy. + +In order to allow for good readings, LeafLabs has tried to isolate at +least some of each board's ADC pins and traces from strong noise +sources. However, there are always trade-offs between noise, +additional functionality, cost, and package size. More information on +these isolated pins is available in each board's hardware +documentation: + +* :ref:`Maple <maple-adc-bank>` +* :ref:`Maple RET6 Edition <maple-ret6-adc-bank>` +* :ref:`Maple Mini <maple-mini-adc-bank>` +* :ref:`Maple Native Beta <maple-native-b-adc-bank>` + +That said, there are a number of more general things you can do to try +to get good readings. If your input voltage changes relatively +slowly, a number of samples can be taken in succession and averaged +together, or the same voltage can even be sampled by multiple ADC pins +at the same time. + +Another important factor when taking a voltage reading is the +reference voltages that the sample is being compared against. For +Maple, the high reference is |vdda| and the low reference is ground. +This means that noise or fluctuations on either |vdda| or ground will +affect the measurement. It also means that the voltage you are trying +to sample must be between ground and 3.3 V. + +.. _adc-range: + +In the case of a variable reading, it is best if the voltage varies +over the entire range of 0 through 3.3 V; otherwise, only a fraction +of the sensitivity is being used. Some basic tools to accomplish this +are `resistor dividers +<http://en.wikipedia.org/wiki/Voltage_divider>`_ and `Zener diodes +<http://en.wikipedia.org/wiki/Zener_diode>`_\ +. However, `operational amplifiers +<http://en.wikipedia.org/wiki/Operational_amplifier>`_ and other +powered components can also be used if greater precision is required. + +.. _adc-recommended-reading: + +Recommended Reading +------------------- + +* `Wikipedia: Analog-to-Digital Converter + <http://en.wikipedia.org/wiki/Analog-to-digital_converter>`_ +* `Arduino Analog Input Tutorial + <http://arduino.cc/en/Tutorial/AnalogInputPins>`_ +* ST documentation: + + * `Application Note on ADC Modes + <http://www.st.com/stonline/products/literature/an/16840.pdf>`_ (PDF) + * `Application Note on ADC Oversampling + <http://www.st.com/stonline/products/literature/an/14183.pdf>`_ (PDF) diff --git a/docs/source/arduino-cc-attribution.txt b/docs/source/arduino-cc-attribution.txt new file mode 100644 index 0000000..ad1c1e0 --- /dev/null +++ b/docs/source/arduino-cc-attribution.txt @@ -0,0 +1,9 @@ +.. Included in all relevant files in order to satisfy the Arduino +.. CC Attribution-ShareAlike 3.0 License + +.. admonition:: License and Attribution + + Portions of this page were adapted from the `Arduino Reference + Documentation <http://arduino.cc/en/Reference/HomePage>`_\ , which + is released under a `Creative Commons Attribution-ShareAlike 3.0 + License <http://creativecommons.org/licenses/by-sa/3.0/>`_. diff --git a/docs/source/arduino-compatibility.rst b/docs/source/arduino-compatibility.rst new file mode 100644 index 0000000..f7d3210 --- /dev/null +++ b/docs/source/arduino-compatibility.rst @@ -0,0 +1,275 @@ +.. highlight:: cpp + +.. _arduino-compatibility: + +============================= + Maple-Arduino Compatibility +============================= + +.. contents:: Contents + :local: + +Overview +-------- + +The biggest difference between the Maple and most Arduino boards is +that the Maple uses a 32-bit ARM Cortex-M3 architecture chip, while +the Arduinos have 8-bit Atmel AVR chips. The different instruction set +means that machine code (which makes up executable binary programs) is +incompatible between the two, and a different compiler (actually just +a different version of `gcc <http://gcc.gnu.org/>`_) is required. + +The compiler for the regular Arduino IDE is the popular `avr-gcc +<http://www.nongnu.org/avr-libc/>`_ package; the compiler for the +Maple version of the IDE is CodeSourcery's edition of gcc for the ARM +EABI target (:command:`arm-non-eabi-gcc`). A (preliminary) reference +on :ref:`using arm-none-eabi-gcc <arm-gcc>` is available. + +The bitwidth of the processor means that the Maple can process 32-bit +operations (like adding or multiplying two 32-bit integers) in a +single instruction, while an Arduino processor would have to split up +large operations into several smaller ones. In a lot of cases 8-bit +operations are plenty (integers 0-255, single characters of text, +etc.), but if you're dealing with higher resolution data, the speed up +could be significant. + +A trade-off is that code could be larger as well; program instructions +and memory locations can be up to 32 bits each. However, removal of +extra instructions and fancy packing together of simple instructions +means that programs aren't much larger (or are even smaller). + +Header Numbering and Incompatibilities +-------------------------------------- + +.. FIXME [Maple-specific values] + +The numbering of headers is different; on the Maple each GPIO has a +unique number: 0, 1, 2, all the way up to 37 (actually, there are +:ref:`a few more <lang-disabledebugports>`...). On the Arduino, the +analog pins are numbered separately (A0-A5) from the digital pins (D0\ +-D13). + +The incompatible hardware differences are: + +* :ref:`I2C <i2c>` **port**: on most Arduinos, the |i2c| port is Analog + Input 4 (SDA) and Analog Input 5 (SCL); on the Maple, |i2c| port 1 + is D5 (SCL) and D9 (SDA), and |i2c| port 2 is D29 (SCL) and D30 + (SDA). + + It should be possible to skywire, sacrificing signal quality (due to + increased capacitance). Alternatively, |i2c| can be bit-banged + reasonably well in software. This peripheral could potentially be + rerouted internally, but we haven't looked into it. + +* :ref:`PWM <pwm>` **on D10**: all the other standard Arduino PWM + headers have PWM functionality on the Maple (D2,D3,D6,D9,D11), but + not D10. + +* **No External Voltage Reference**: The Arduino has an AREF pin which + allows the use of an external ADC voltage reference; the Maple has + an extra GPIO pin (D14) with PWM capability in this spot, and does + not allow an external voltage reference to be configured. + +* **EEPROM**: the Maple does not have any internal EEPROM. This + functionality can be emulated with regular persistent flash memory, + or with an external EEPROM chip. + +* **ISP Programming**: the Maple does not use an ISP/ICSP bus for + debugging; it uses :ref:`JTAG <jtag>`. + + +Software Language/Library Changes +--------------------------------- + +With :ref:`a few exceptions <language-missing-features>`, the entire +Wiring/Arduino language is supported. However, there are some subtle +differences, most of which are improvements: + +* **32-bit integers**: many standard functions either expect or return + full 32-bit (4 byte) integer values instead of the regular 16-bit (2 + byte) Arduino values. + +* **64-bit doubles**: The :ref:`double <lang-double>` type is a full + double-precision floating point type on the Maple; it is a + single-precision floating point value on the Arduino. + +* :ref:`pinMode() <lang-pinmode>` **types**: any :ref:`GPIO <gpio>` + (including analog pins) can be configured into one of the following + modes with a single call to ``pinMode()``: ``OUTPUT``, + ``OUTPUT_OPEN_DRAIN``, ``INPUT_FLOATING``, ``INPUT_PULLUP``, + ``INPUT_PULLDOWN``. Additionally, the PWM pins (labeled "PWM" on the + silkscreen) can be configured in ``PWM`` and ``PWM_OPEN_DRAIN`` + modes, and the analog input pins (labeled "AIN") can be configured + in ``INPUT_ANALOG`` mode. See the :ref:`GPIO documentation <gpio>` + for more information. + +* :ref:`Serial port <lang-serial>` **syntax**: like the `Arduino Mega + <http://arduino.cc/en/Main/ArduinoBoardMega>`_, the Maple has + multiple :ref:`USART ports <lang-serial>`. By default, ``Serial`` + is not mapped to any of them. Use ``Serial1`` through ``Serial3`` + instead. + +* **16-bit** :ref:`PWM <pwm>`: Arduino boards support 8-bit PWM, which + means that calls to :ref:`analogWrite() <lang-analogwrite>` take + values between 0 (always off) and 255 (always on). The Maple + supports 16-bit PWM, so the corresponding values should be between 0 + (always off) and 65535 (always on). + +* **12-bit** :ref:`ADC <adc>`: Arduino boards support 10-bit ADC, which + means that calls to :ref:`analogRead() <lang-analogread>` will + return values between 0 and 1023. The Maple supports 12-bit ADC, so + the same call will instead return values between 0 and 4095. + +Shield and Device Compatibility +------------------------------- + +**Can't find your shield?** Check out the `Compatible Shields +<http://wiki.leaflabs.com/index.php?title=Compatible_Shields>`_ page +on our wiki. + +.. list-table:: + :header-rows: 1 + + * - Shield/Device + - Compatible? + - Notes + + * - Ethernet shield + - Yes! + - Tested; no library yet + + * - WiFi Shield + - Yes! + - Tested; preliminary library support + + * - MIDI shield + - Yes! + - Tested; no library yet + + * - XBee shield + - Unknown + - + + * - Bluetooth shield + - Unknown + - Some Bluetooth <-> UART boards have been tested and are known + to work. + + * - Cellular shield + - Unknown + - + +Library Porting Status +---------------------- + +The state of currently ported Arduino libraries is the +:ref:`libraries`. + +.. TODO Update as libraries are ported. + +.. list-table:: + :header-rows: 1 + + + * - Library + - Ported? + - Notes + + * - Wire + - Preliminary + - In progress; see :ref:`library reference <libraries-wire>`. + + * - LiquidCrystal + - **Yes** + - :ref:`Included since IDE 0.0.7 <libraries-liquid-crystal>` + + * - Ethernet + - Not yet + - Planned + + * - EEPROM + - (Unsupported) third-party emulation + - The Maple doesn't have EEPROM; it uses flash instead. There is + an `EEPROM emulation library + <http://akb77.com/g/stm32/maple-eeprom-emulation-library/>`_ by + `x893 <http://akb77.com/g/>`_, but we haven't tested it. + + * - Firmata + - Not yet + - Planned + + * - Matrix + - Not yet + - Planned + + * - Servo + - **Yes** + - :ref:`Included since IDE 0.0.9 <libraries-servo>` + + * - SoftwareSerial + - Not yet + - Planned + + * - Sprite + - Not yet + - Planned + + * - Stepper + - Not yet + - Planned + +Sketch and Library Porting HOWTO +-------------------------------- + +In addition to the suggestions in this section, you may find many of +the individual :ref:`language reference <language>` pages useful. As +appropriate, these have "Arduino Compatibility" sections; one good +example is the :ref:`analogWrite() <lang-analogwrite-compatibility>` +function. + +- Check the hardware and header differences above, and see if your + project or shield needs to be modified (eg, add 3.3V level + converters or reroute PWM to header D10). + +- Check for ported library functionality. We intend to port all of the + core and popular libraries (like Wire, Ethernet, and the LCD screen + driver), but this task is not yet finished. (:ref:`Patches are + welcome! <libmaple-contributing>`). + +- Check for peripheral conflicts; changing the configuration of timers + and bus speeds for a feature on one header may impact all the + features on that hardware "port". For example, changing the timer + prescaler to do long PWM pulses could impact |i2c| communications on + nearby headers. + +- Rewrite any low-level code. This could potentially be very + difficult, but hopefully you've used the Arduino libraries to + abstract away the registers and other hardware-specific + details. Your sketch probably doesn't have any low-level code; a + library which wraps a particular peripheral very well may. Some + help is available in the :ref:`arm-gcc` reference. + +- Redeclare variable sizes if necessary: generics like ``int`` will + probably work unless you depend on side-effects like rollover. + +- Check every ``pinMode()``: the Maple has more modes for GPIO + pins. For example, make sure to set analog pins to ``INPUT_ANALOG`` + before reading and PWM pins to ``PWM`` before writing. The full set + of pin modes is documented in the :ref:`lang-pinmode` reference. + +- Modify PWM writes: ``pinMode()`` must be set to ``PWM``, the + frequency of the PWM pulse configured, and the duty cycle written + with up to 16-bit resolution. + +- Modify ADC reads: :ref:`lang-analogread` takes the full pin number + (not 0-5) and returns a full 12-bit reading. The ADC pin must have + its ``pinMode()`` set to ``INPUT_ANALOG``. + +- Possibly convert all Serial-over-USB communications to use + :ref:`lang-serialusb` instead of a USART :ref:`serial port + <lang-serial>`. The Maple has a dedicated USB port which is not + connected to the USART TX/RX pins in any way. + +- Check timing: Maple clock cycles are just 13.9 nanoseconds, though + the peripheral bus speeds (which limit GPIO output) are clocked + slower. diff --git a/docs/source/arm-gcc.rst b/docs/source/arm-gcc.rst new file mode 100644 index 0000000..30667a2 --- /dev/null +++ b/docs/source/arm-gcc.rst @@ -0,0 +1,107 @@ + +.. _arm-gcc: + +GCC and libc +============ + +This document provides notes on using ``arm-none-eabi-gcc``, the +`CodeSourcery <http://www.codesourcery.com/>`_ version of the GNU `GCC +<http://gcc.gnu.org/>`_ compilers used for the Maple boards. It is +not intended as a reference manual for GCC; such manuals are available +`elsewhere <http://gcc.gnu.org/>`_. + +.. contents:: Contents + :local: + +Obtaining ``arm-none-eabi-gcc`` +------------------------------- + +Recent versions of ``arm-none-eabi-gcc`` and associated tools are +included with the :ref:`Maple IDE <ide>`. + +Users who wish to use ``arm-none-eabi-gcc`` directly, along with a +standard Unix Make-based toolchain, should read the +:ref:`unix-toolchain`, which describes how to set up such an +environment. + +LeafLabs maintains `mirrors +<http://static.leaflabs.com/pub/codesourcery/>`_ for some of the more +recent versions of the compiler, including versions for OS X, Win32, +and 32-bit Linux. + +.. _arm-gcc-compiler-flags: + +Compiler Flags Used by libmaple +------------------------------- + +This section documents the flags passed to ``arm-none-eabi-gcc`` by +the :ref:`Maple IDE <ide>` and the default Makefile provided with the +:ref:`Unix toolchain <unix-toolchain>`. The information in this +section is subject to change between :ref:`libmaple <libmaple>` +releases. + +.. highlight:: sh + +The following flags are among those passed to the C compiler:: + + -Os -g -mcpu=cortex-m3 -mthumb -march=armv7-m -nostdlib + -ffunction-sections -fdata-sections -Wl,--gc-sections + +In addition to those flags just given for the C compiler, the +following flags are among those passed to the C++ compiler:: + + -fno-rtti -fno-exceptions -Wall + +The following flags are among those passed to the assembler:: + + -mcpu=cortex-m3 -march=armv7-m -mthumb + +.. highlight:: cpp + +.. _arm-gcc-libc: + +Using the C Standard Library +---------------------------- + +By default (under both the :ref:`Maple IDE <ide>` and the :ref:`Unix +toolchain <unix-toolchain>`), ``arm-none-eabi-gcc`` is configured to +link against `newlib <http://sourceware.org/newlib/>`_, a C standard +library intended for use with embedded applications. You are free to +include of any of its headers. + +Be advised, however, that a variety of syscalls may only be partially +implemented, if at all. See the :ref:`libmaple` file syscalls.c and +the newlib documentation for more details. + +.. _arm-gcc-avr-gcc: + +Switching from AVR-GCC +---------------------- + +This section, which is expected to grow over time, describes +techniques for porting code which uses AVR-GCC features (AVR-GCC is +the compiler used by many Atmel AVR-based microcontroller boards, +including Arduino) for use on the Maple. + +.. _arm-gcc-attribute-flash: + +- Replacing ``PROGMEM``: If you need to store a lot of constant data, + you can store variables in Flash (instead of RAM) by using the + libmaple macro ``__FLASH__``. Here's an example:: + + uint32 array[] __FLASH__ = {0, 1, 2}; + + This will help you save RAM when you need to store large amounts of + data, like look-up tables. + + You can only store values which are compile-time constants (like + numbers and strings, and arrays of numbers and strings) in this way. + Also, if you try to change a variable stored in Flash, your program + will crash. + + If you need to port over AVR/Arduino code that uses pgmspace.h, + these declarations may help you:: + + typedef const unsigned char prog_uchar; + #define pgm_read_byte_near(x) (*(prog_uchar*)x) + #define pgm_read_byte(x) (*(prog_uchar*)x) diff --git a/docs/source/bootloader.rst b/docs/source/bootloader.rst new file mode 100644 index 0000000..23b0448 --- /dev/null +++ b/docs/source/bootloader.rst @@ -0,0 +1,750 @@ +.. highlight:: sh + +.. _bootloader: + +Maple Bootloader(s) +=================== + +The firmware which allows the Maple to be reprogrammed via a USB +connection. Every Maple board comes programmed with this by default, +and it is not overwritten by regular programs (it lives lower in the +Flash memory and only runs when the chip is reset). + +**Check out the latest source code version:** :: + + git clone git://github.com/leaflabs/maple-bootloader.git + +**Visit the GitHub development project**: https://github.com/leaflabs/maple-bootloader + +.. contents:: Contents + :local: + +Bootloader Schemes Explained +---------------------------- + +Maple Rev 3 and Rev 5 (Rev 5 is the version currently shipping) +represents a drastic remake of the core library as well as the upload +process. Thes changes to the bootloader, were implemented to resolve +platform-specific issues on Windows. Before delving into how the Rev +1 bootloader worked and how the Rev 5 bootloader works now, we'll +discuss the features common to each and touch a bit on the Arduino +setup. + +This is a fairly involved explanation, with a lot of details that are +likely only interesting to a few. If you just want to get the rough +idea, skim this article. If you want to start hacking on the +bootloader, get in touch with us to get even more info on how this all +works. And finally, you can always `check out the code at GitHub +<https://github.com/leaflabs/libmaple>`_! + +Arduino +------- + +Arduino is based off of AVR series microcontrollers, most of which +lack USB support. Thus, boards like the Duemilanove add USB capability +via an FTDI USB-to-Serial converter chip. This chip interfaces with +the AVR over an RS-232 serial interface. When you plug an Arduino into +a computer, only an FTDI driver is needed. Since the FTDI chip is +separate from the AVR, you can reset the Arduino without closing this +USB connection with the FTDI chip. + +To program an Arduino, the host machine sends a command over the USB +pipe (reset DTR) which in turn resets the AVR. The AVR will boot into +a bootloader, which waits for a second for any upload commands over +serial. The host machine can either send those commands, or do +nothing. If it does nothing, the AVR will quickly jump to user code +and off you go. The whole process is quick, the bootloader doesn’t +live for very long, and will exit almost immediately if no upload +commands are received. + +Maple Rev 1 +----------- + +Maple is based off the STM32 (ARM cortex M3) series chips, which do +have embedded USB support. Thus, Maple doesn’t need the extra FTDI +chip. Firmware is uploaded via the standard DFU protocol (also used by +iPhone and openMoko). Since DFU is a standard, there is no need for +custom software running on the host to upload the firmware. Any DFU +compliant program will work. The Maple IDE is based around +:command:`dfu-util`, openMoko’s DFU utility. Using DFU came at a cost, +however. The USB port must additionally implement a separate serial +port at the same time (we use the CDC ACM class for serial +functionality). + +Maple Rev 1 attempted to run both DFU and CDC ACM devices +simultaneously on the USB peripheral. On Linux, this worked great. The +OS would service the DFU driver during uploads, and the CDC ACM for +serial port transactions. There was no reset necessary for uploads. No +waiting. The bootloader was always running the background, ready to +receive commands. + +The problem was that *only* Linux did this. Windows refused to attach +more than one driver to a single USB device without repackaging the +DFU and CDC ACM into a single IAD Compound Device. It's not terribly +important what this means, except for two things. + +1. Four drivers were necessary to make everything work. +2. IAD is not supported by OS X. + +Mac OS X, on the other hand, only supported Compound USB, a different +trick that is not supported by Windows. While a perpetual background +bootloader was attractive, it became clear, after much toiling, we +were going to have to write custom drivers across several platforms to +make everything work this way. + +.. _bootloader-rev3: + +Maple Rev3/Rev5 - DFU +--------------------- + +Maple Rev 3 takes a completely different tack, more along the lines of +Arduino. In Rev 3, the device resets into bootloader mode, which +stays alive for a few moments to receive commands, and then jumps to +user code. The bootloader is implemented as a DFU device -- just a DFU +device, no serial port. This requires one driver for Windows +(:file:`drivers/mapleDrv/dfu` in the Windows IDE directory). + +As part of the :ref:`libmaple <libmaple>` library, user code is +automatically supplied with serial support via some behind the scenes +work (``setupUSB()`` is called from ``init()``). This user mode code +only implements a CDC ACM class USB device, giving you functions like +:ref:`SerialUSB.read() <lang-serialusb-read>`. Separating these two +modes fixed the driver issues and works well across platforms, +requiring only two drivers (serial and DFU) on Windows. + +However, it is no longer possible to upload code at will, since there +is no bootloader quietly listening in the background. Instead, you +must reset the board, then initiate a DFU transaction. The IDE +performs this reset automatically by performing a special sequence of +changes on the USB serial port: + +1. Pulse DTR (high and then low, so that you've created a negative + edge) +2. Write "1EAF" in ASCII over the serial pipe. This will cause Maple + to reset. Only the first 4 bytes after a negative edge of DTR are + checked for this command, so it's important you actually create a + negative edge, rather than just ensuring DTR is low. + +After the reset, the host OS takes a few moments (.5-2 seconds) to +re-enumerate the device as DFU. This delay is unpredictable, and is +the reason the bootloader on Maple Rev 3/Rev 5 stays alive for so +long. (Sometimes, the bootloader was exiting before the OS had even +enumerated the device.) + +Once in bootloader mode, :command:`dfu-util` uploads your sketch into +either flash or RAM (DFU alternate setting 0 or 1, respectively) and +resets the board again. This time, however, no DFU transaction is +initiated, and the bootloader gives way to user code, closing down the +DFU pipe and bringing up the USB serial port. + +.. .. _bootloader-rev6: + +.. Maple Rev6 - The Serial Bootloader (Tentative) +.. ---------------------------------------------- + +.. .. note:: This section documents an in-progress version of the Maple +.. bootloader. **No Maples yet sold use this bootloader protocol**. +.. It has not been yet been publicly released, and its interface is +.. not stable. + +.. The bootloader in Rev3/Rev5 works well on Linux, acceptably on Mac, +.. but was unsatisfactory on Windows. Unlike the other operating systems, +.. Windows needed to be manually pointed to both the driver to use for +.. programming (DFU, via `libusb <http://www.libusb.org/>`_) and the +.. driver to use for serial communication (usbser.sys, built in to +.. Windows). Since Maple operates in only one of these modes at a time, +.. driver installation was unnecessarily complicated. It was necessary to +.. bring Maple into the correct mode before installing each of the +.. drivers. Furthermore, because libusb is not bundled with Windows, and +.. its driver is not signed, Windows 7 users have been forced to +.. laboriously disable driver signing checks. Finally, Windows hates the +.. constant switching of the device between Serial and DFU modes (during +.. programming), and often prompts users to install drivers that are +.. already installed. We have therefore decided to abandon DFU. + +.. In our new bootloader scheme, Maple is simply a serial device. +.. Windows comes bundled with usbser.sys, so no driver signing is +.. required. The IDE installation process is greatly simplified, there +.. is no more switching back and forth between "modes", and we can build +.. in new functionality outside the DFU spec. + +.. The first incarnation of this serial-only bootloader leaves libmaple +.. and user code untouched. However, during programming, instead of +.. calling :command:`dfu-util` to upload code we will now call a newly +.. written utility script similar to `avr-dude +.. <http://savannah.nongnu.org/projects/avrdude/>`_. The high level +.. operation of the bootloader will remain the same - come on at startup, +.. wait for an upload operation or timeout, and jump to user code. + +.. The second version of this bootloader will eliminate this dependence +.. on resetting and timing out by having the bootloader run in the +.. background. It will additionally own the serial port. In this scheme, +.. sending data over the COM port while DTR is pulled low results in that +.. packet being captured by the bootloader and interpreted as a +.. bootloader command. When the user uploads a new program, the +.. bootloader will overwrite the old one, reset the various peripheral +.. registers, and jump to user code. All of this will occur without +.. resetting the chip and thus causing Maple to connect and disconnect +.. from your computer (which seems to cause many problems). + +.. The final version of this bootloader scheme will involve a separate +.. microcontroller, whose responsibilities are to drive the USB port, +.. program the main processor, and offer some amount of debugging +.. capability. This will allow user sketches to run on the bare metal of +.. the main processor, without any bootloader hiding underneath. This +.. approach is similar to the approaches taken by mbed and the Arduino +.. Uno. + +.. Regardless of which generation of the new serial bootloader you are +.. working with, the command interface is the same. The low level +.. communication protocol is inspired by STK-500, the protocol used to +.. program many AVR-based development boards. The protocol is a +.. packetized query-response scheme. The host PC initiates every +.. transaction, and for every query sent to the bootloader, a single +.. response will be returned (or the system times out). Data is +.. transmitted over 115.2kbps, 8 data bits, 1 stop bit, no parity +.. bit. Every query or response follows the same packet format that looks +.. like this: + +.. .. _bootloader-packet-structure: + +.. Packet Structure +.. ^^^^^^^^^^^^^^^^ + +.. A bootloader packet is composed of a sequence of fields, as follows. + +.. .. list-table:: +.. :header-rows: 1 + +.. * - Field +.. - Length (bytes) +.. - Value +.. - Description + +.. * - START +.. - 1 +.. - 0x1B +.. - Magic constant, indicates bootloader packet + +.. * - SEQUENCE_NUM +.. - 1 +.. - 0--0xFF +.. - Queries and responses must have the same sequence number; rolls +.. over to 0 after 0xFF + +.. * - MESSAGE_SIZE +.. - 2 +.. - 0--0xFFFF +.. - Size of message body, currently limited to a 1024B=1KB maximum + +.. * - TOKEN +.. - 1 +.. - 0x7F +.. - Differs from STK500 value of 0x0E + +.. * - MESSAGE_BODY +.. - Variable, determined by MESSAGE_SIZE field +.. - Command query or response +.. - See :ref:`next section <bootloader-commands>` + +.. * - CHECKSUM +.. - 4 +.. - XOR of all other 32-bit words in packet +.. - See :ref:`below <bootloader-checksum>` + +.. .. _bootloader-checksum: + +.. .. highlight:: cpp + +.. .. note:: When computing the checksum, the words in a packet are +.. interpreted big-endian (as if the packet were a sequence of 32-bit, +.. big-endian unsigned integers). If the end of the MESSAGE_BODY is +.. not aligned with a four-byte boundary, then the checksum will treat +.. it as if it was padded with zero bytes to a four-byte boundary. + +.. As a concrete example, an entire GET_INFO query (see :ref:`below +.. <bootloader-get-info>`), including the packet structure, is +.. comprised of the byte sequence :: + +.. {0x1B, 0x7F, 0x00, 0x01, 0x7F, 0x00, 0x64, 0x7F, 0x00, 0x01} + +.. The SEQUENCE_NUM of this query is 0x7F. + +.. .. highlight:: sh + +.. .. _bootloader-commands: + +.. Commands +.. ^^^^^^^^ + +.. The packet structure overhead is for reliability. The actual queries +.. and responses are transacted inside of the message body. Following +.. the STK-500 protocol, each query or response begins with the single +.. byte command field. For each query, the resultant response must begin +.. with the same CMD byte. For each type of command, the structure of +.. queries and responses is of fixed size. + +.. Also following STK-500, fields longer than 1 byte are transmitted MSB +.. first (big-endian). However, READ and WRITE commands operate byte-wise +.. (not word-wise); it is up to the host PC to ensure that alignment and +.. ordering issues are handled appropriately. + +.. .. _bootloader-get-info: + +.. GET_INFO +.. """""""" + +.. Used to query device characteristics. + +.. GET_INFO Query: + +.. .. list-table:: +.. :header-rows: 1 + +.. * - Field +.. - Bytes +.. - Comments + +.. * - GET_INFO +.. - 1 +.. - Value 0 + +.. GET_INFO Response: + +.. .. list-table:: +.. :header-rows: 1 +.. :widths: 4 2 10 + +.. * - Field +.. - Bytes +.. - Comments + +.. * - GET_INFO +.. - 1 +.. - Value 0 + +.. * - Endianness +.. - 1 +.. - 0 indicates little-endian, 1 indicates big-endian. +.. (Currently returns 0; this field allows for future +.. expansion). + +.. * - Available Ram +.. - 4 +.. - In bytes + +.. * - Available Flash +.. - 4 +.. - In bytes + +.. * - Flash Page Size +.. - 2 +.. - In bytes + +.. * - Starting Address (FLASH) +.. - 4 +.. - Usually 0x08005000 + +.. * - Starting Address (RAM) +.. - 4 +.. - Usually 0x200000C0 + +.. * - Bootloader Version +.. - 4 +.. - Current version 0x00060000 (MAJ,MIN) + +.. .. _bootloader-erase-page: + +.. ERASE_PAGE +.. """""""""" + +.. Used to erase flash pages. + +.. ERASE_PAGE query: + +.. .. list-table:: +.. :header-rows: 1 +.. :widths: 4 2 10 + +.. * - Field +.. - Bytes +.. - Comments + +.. * - ERASE_PAGE +.. - 1 +.. - Value 1 + +.. * - ADDRESS +.. - 4 +.. - Will erase whichever page contains ADDRESS + +.. ERASE_PAGE response: + +.. .. list-table:: +.. :header-rows: 1 +.. :widths: 3 2 10 + +.. * - Field +.. - Bytes +.. - Comments + +.. * - ERASE_PAGE +.. - 1 +.. - Value 1 + +.. * - SUCCESS +.. - 1 +.. - Either 0 (failure) or 1 (success) + +.. WRITE_BYTES +.. """"""""""" + +.. Used to write to RAM or flash. + +.. WRITE_BYTES query: + +.. .. list-table:: +.. :header-rows: 1 +.. :widths: 4 4 10 + +.. * - Field +.. - Bytes +.. - Comments + +.. * - WRITE_BYTES +.. - 1 +.. - Value 2 + +.. * - Starting Address +.. - 4 +.. - Can address arbitrary RAM, or :ref:`cleared +.. <bootloader-erase-page>` flash pages. + +.. * - DATA +.. - MESSAGE_SIZE - 5 +.. - See :ref:`Packet Structure <bootloader-packet-structure>` + +.. WRITE_BYTES response: + +.. .. list-table:: +.. :header-rows: 1 +.. :widths: 2 2 10 + +.. * - Field +.. - Bytes +.. - Comments + +.. * - WRITE_BYTES +.. - 1 +.. - Value 2 + +.. * - SUCCESS +.. - 1 +.. - Either 0 (failure) or 1 (success). Will fail if writes were +.. made to uncleared pages. Does not clean up failed writes +.. (memory will be left in an undefined state). + +.. READ_BYTES +.. """""""""" + +.. Used to read from RAM or flash. + +.. READ_BYTES query: + +.. .. list-table:: +.. :header-rows: 1 +.. :widths: 2 2 10 + +.. * - Field +.. - Bytes +.. - Comments + +.. * - READ_BYTES +.. - 1 +.. - Value 3 + +.. * - ADDRESS +.. - 4 +.. - Start of block to read. Must be a multiple of 4. + +.. * - LENGTH +.. - 2 +.. - Maximum number of bytes to read (currently, this may be at most +.. 1024 = 1KB). Must be a multiple of 4. + +.. READ_BYTES response: + +.. .. list-table:: +.. :header-rows: 1 +.. :widths: 2 2 10 + +.. * - Field +.. - Bytes +.. - Comments + +.. * - READ_BYTES +.. - 1 +.. - Value 3 + +.. * - DATA +.. - MESSAGE_SIZE - 1 +.. - Contains read bytes. The actual number of bytes read may be +.. less than the LENGTH field of the corresponding READ_BYTES +.. query. If this section is of length 0, this should be +.. interpreted as a read failure. See +.. :ref:`bootloader-packet-structure`. + +.. JUMP_TO_USER +.. """""""""""" + +.. Causes the bootloader to jump to user code's starting address. + +.. JUMP_TO_USER query: + +.. .. list-table:: +.. :header-rows: 1 +.. :widths: 2 1 10 + +.. * - Field +.. - Bytes +.. - Comments + +.. * - JUMP_TO_USER +.. - 1 +.. - Value 4 + +.. * - Location +.. - 1 +.. - 0 means jump to flash starting address, 1 means jump to RAM +.. starting address. See the :ref:`bootloader-get-info` command +.. for more information. + +.. JUMP_TO_USER response: + +.. .. list-table:: +.. :header-rows: 1 +.. :widths: 2 1 10 + +.. * - Field +.. - Bytes +.. - Comments + +.. * - JUMP_TO_USER +.. - 1 +.. - Value 4 + +.. * - SUCCESS +.. - 1 +.. - Either 0 (failure) or 1 (success). If successful, after the +.. response is sent, the bootloader ends this session and jumps to +.. the user code in flash or RAM as specified in the query's +.. Location field. + + +.. SOFT_RESET +.. """""""""" + +.. Engages a full software reset. + +.. SOFT_RESET query: + +.. .. list-table:: +.. :header-rows: 1 +.. :widths: 2 1 10 + +.. * - Field +.. - Bytes +.. - Comments + +.. * - SOFT_RESET +.. - 1 +.. - Value 5 + +.. SOFT_RESET response: + +.. .. list-table:: +.. :header-rows: 1 +.. :widths: 2 1 10 + +.. * - Field +.. - Bytes +.. - Comments + +.. * - SOFT_RESET +.. - 1 +.. - Value 5 + +.. * - SUCCESS +.. - 1 +.. - Either 0 or 1 (FAILED and OK, respectively). Will end this +.. bootloader session and reset the processor. + +.. _bootloader-reflashing: + +Flashing A Custom Bootloader +---------------------------- + +.. warning:: This section is for users who want to put a fresh or + custom bootloader on their board. It's possible to make a mistake + in this process and e.g. render your Maple unable to communicate + with the IDE. Know what you're doing, and proceed with caution. + +The STM32 microprocessor on the Maple comes with a built-in serial +bootloader that can be used to flash a new (software) bootloader onto +the chip. While the Maple bootloader is just a program, the built-in +serial bootloader is part of the STM32 hardware, so it's always +available. + +This means that you can **always** follow these instructions to put a +new bootloader program on your board; it **doesn't matter** if there's +already a copy of the Maple bootloader on it or not. + +If you have a Maple Rev 1; you don't have a BUT button, and won't be +able to follow these directions. A workaround is detailed in `this +forum posting <http://forums.leaflabs.com/topic.php?id=32#post-126>`_. + +.. highlight:: sh + +Setup +^^^^^ + +In order to follow these instructions, you will need: + +- A binary of the bootloader you want to upload (see below). +- Hardware for communicating between the Maple and your computer over + serial. +- `Python <http://python.org>`_, version 2.5 or higher. +- The `PySerial <http://pyserial.sourceforge.net/>`_ library (this + must be installed separately; it is not part of the Python standard + library). + +**Step 1: Obtain a bootloader binary**. If you want to re-flash the +"factory-default" bootloader, LeafLabs hosts pre-compiled copies: + +- `Maple <http://static.leaflabs.com/pub/leaflabs/maple-bootloader/maple_boot.bin>`_ +- `Maple Mini <http://static.leaflabs.com/pub/leaflabs/maple-bootloader/maple_mini_boot.bin>`_ +- `Maple RET6 Edition <http://static.leaflabs.com/pub/leaflabs/maple-bootloader/maple_RET6_boot.bin>`_ +- `Maple Native <http://static.leaflabs.com/pub/leaflabs/maple-bootloader/maple_native_boot.bin>`_ + +To flash a customized version of a LeafLabs bootloader, you can run +(on a :ref:`suitably configured system <unix-toolchain>`) the +following to obtain a bootloader binary:: + + $ git clone git://github.com/leaflabs/maple-bootloader.git + $ cd maple-bootloader + $ make + $ ls -lh build/maple_boot.bin # this is the compiled bootloader binary + +.. note:: If you plan to write a totally custom bootloader, you'll + need an actual binary to use these instructions. An ASCII + representation of the binary, such as the Intel .hex format, won't + work. + +**Step 2: Connect Maple Serial1 to your computer**. +There are a variety of ways of doing this. We use Sparkfun's `FTDI +breakout boards <http://www.sparkfun.com/products/718>`_, but you +could use another Maple, an Arduino, etc. -- anything that allows your +computer to communicate with the Maple you want to reprogram over a +serial interface. + +If you do use an FTDI breakout board, first make sure your Maple is +disconnected from an external power source, be it battery, USB, or +barrel jack. Then, connect the FTDI board's TX pin to ``Serial1``\ 's +RX pin (labeled "RX1" on the silkscreen), FTDI RX to ``Serial1`` TX +(labeled "TX1"), FTDI ground to ground (labeled GND), and its 3.3V pin +to Vin. On Maple Mini, you will also need to tie BOOT1 (pin 2) to +ground. + +More information on ``Serial1`` is available :ref:`here +<lang-serial>`. + +At this point, you're ready to plug the FTDI board into your computer +(via USB). + +**Step 3: Run the built-in hardware serial bootloader**\ +[#fserbootmode]_. Accomplish this using the following steps: + +1. Press and hold the reset and BUT buttons. +2. Release the reset button *without releasing BUT*. +3. Release BUT. + +At this point, if you followed the instructions correctly, the board +will appear unresponsive -- the LED won't blink, etc. Don't worry. +This is the expected behavior for the serial bootloader. + +Do not confuse the above steps, which run the built-in serial +bootloader, with the steps for :ref:`perpetual bootloader mode +<troubleshooting-perpetual-bootloader>`. + +**Step 4: Get stm32loader.py**. You can download it directly from +`libmaple's GitHub page +<https://github.com/leaflabs/libmaple/raw/master/support/stm32loader.py>`_ +(click the link, then save the file somewhere on your system). If you +have set up the :ref:`Unix toolchain <unix-toolchain>`, it's the file +libmaple/support/stm32loader.py. + +Flashing the new Bootloader +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +We'll use ``maple_boot.bin`` as the path to the bootloader binary from +Step 1, and ``ser-port`` as the Maple's serial port device file or COM +port. + +* On **Linux**, ``ser-port`` will probably be something like + ``/dev/ttyUSB0``, although the exact number could be different (it + could be ``/dev/ttyUSB1``, ``/dev/ttyUSB2``, etc.). + +* On **OS X**, ``ser-port`` will probably look like + ``/dev/tty.usbserialXXXX``, where ``XXXX`` is some random string of + characters. + +* On **Windows**, ``ser-port`` will be something like ``COM1``, ``COM2``, etc. + +.. highlight:: sh + +To upload a bootloader binary, run this command from the Unix shell:: + + python stm32loader.py -p ser-port -evw maple_boot.bin + +Or this command from the Windows command prompt:: + + python.exe stm32loader.py -p ser-port -evw maple_boot.bin + +You can also run the following to get usage information:: + + # Unix: + python stm32loader.py -h + + # Windows: + python.exe stm32loader.py -h + +If all goes well, you'll see a bunch of output, then "Verification +OK". Your board now has a fresh bootloader installed. + +The first time you upload a program after installing a new bootloader, +there is no need to select a serial port in the :ref:`IDE <ide>` +[#fbootser]_. Perform this first upload with no serial port selected. +The IDE will emit a warning about not finding a serial port, but the +upload will still succeed. In subsequent uploads, select a serial +port as you normally would. + +If something goes wrong, the `forum`_ is probably your best bet for +obtaining help, with IRC (server irc.freenode.net, channel +#leafblowers) being another option. If all else fails, you can always +`contact us directly`_! + +.. rubric:: Footnotes + +.. [#fbootser] This is because immediately after installing a new + bootloader, the only program on your board is the + bootloader itself. Unlike a normal sketch, the + bootloader is not enumerated as a virtual serial port + (it uses DFU instead; see :ref:`above + <bootloader-rev3>` for more details). + +.. [#fserbootmode] Resetting your board in this way runs a special + bootloader that ST builds into their chips' + hardware, which communicates over :ref:`usart`. + This is different from the LeafLabs bootloader, + which is a normal program that runs on your board, + and communicates over :ref:`usb`. diff --git a/docs/source/conf.py b/docs/source/conf.py new file mode 100644 index 0000000..f4a9bbb --- /dev/null +++ b/docs/source/conf.py @@ -0,0 +1,283 @@ +# -*- coding: utf-8 -*- +# +# libmaple documentation build configuration file, created by +# sphinx-quickstart on Thu Oct 7 06:42:30 2010. +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys, os +import os.path + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +# We rely on Michael Jones's breathe as a Doxygen-to-Sphinx bridge. +# See the README for information on obtaining it and letting Sphinx +# know where it is. +sys.path.append(os.environ['BREATHE_HOME']) + +# -- General configuration ---------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +#needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', + 'sphinx.ext.intersphinx', 'sphinx.ext.todo', + 'sphinx.ext.coverage', 'breathe'] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The encoding of source files. +#source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = 'contents' + +# General information about the project. +project = u'Maple' +copyright = u'2010, 2011, LeafLabs, LLC' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = '0.0' +# The full version, including alpha/beta/rc tags. +# FIXME [RELEASE] update this for the release +release = 'custom-build' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +#language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = ['epilog.rst', 'prolog.rst'] + +# Included at the end of every source file that is read. +with open('epilog.rst', 'r') as ep: + rst_epilog = ep.read() + +# Included at the beginning of every source file that is read. +with open('prolog.rst', 'r') as pr: + rst_prolog = pr.read() + +# The reST default role (used for this markup: `text`) to use for all +# documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + +# Warn about all references where the target cannot be found. +nitpicky = True + +# -- Options for HTML output -------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = 'default' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +html_theme_options = { + ## Sidebar placement options + #'stickysidebar' : 'true', + 'rightsidebar' : 'true', + #'collapsiblesidebar' : 'true', + + ## Color + 'sidebarbgcolor' : '#C8C8C8', + 'sidebarlinkcolor' : 'green', + 'sidebartextcolor' : 'black', + #'sidebarbtncolor' : 'black', + 'footerbgcolor' : 'green', + 'relbarbgcolor' : 'green', + 'headlinkcolor' : '#000000', + 'linkcolor' : 'green', + #'visitedlinkcolor' : 'green', + + ## Font + 'headfont' : 'Georgia', + 'bodyfont' : 'Lucida' +} + +# Add any paths that contain custom themes here, relative to this directory. +#html_theme_path = ['_static'] + +# The name for this set of Sphinx documents. If None, it defaults to +# "<project> v<release> documentation". +html_title = project + ' v' + release + +# A shorter title for the navigation bar. Default is the same as html_title. +html_short_title = 'Index' + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +# html_logo = '_static/img/round_logo_60x60.png' + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +html_favicon = '_static/img/round_logo_32x32.ico' + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +html_sidebars = { + '**': ['globaltoc.html', 'searchbox.html'], +} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +html_additional_pages = { + 'index': 'indexcontent.html' +} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +html_use_index = False + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +#html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +#html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a <link> tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = None + +# Output file base name for HTML help builder. +htmlhelp_basename = 'mapledoc' + + +# -- Options for LaTeX output ------------------------------------------------- + +# The paper size ('letter' or 'a4'). +#latex_paper_size = 'letter' + +# The font size ('10pt', '11pt' or '12pt'). +#latex_font_size = '10pt' + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target file, title, author, documentclass [howto/manual]) +latex_documents = [ + ('index', 'maple.tex', u'Maple Documentation', + u'LeafLabs, LLC', 'manual'), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# If true, show page references after internal links. +#latex_show_pagerefs = False + +# If true, show URL addresses after external links. +#latex_show_urls = False + +# Additional stuff for the LaTeX preamble. +#latex_preamble = '' + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_domain_indices = True + + +# -- Options for manual page output ------------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + ('index', 'maple', u'Maple Documentation', + [u'LeafLabs, LLC'], 1) +] + + +# Example configuration for intersphinx: refer to the Python standard library. +#intersphinx_mapping = {'http://docs.python.org/': None} + + +# -- Options for breathe integration ------------------------------------------ + +# We allow people to check in Doxygen XML into maintenance branches. +doxygen_xml_maybe = os.path.join(os.path.dirname(os.path.dirname(__file__)), + 'doxygen', 'xml') +if os.path.isdir(doxygen_xml_maybe): + # There's a doxygen/xml/ directory in this repository root, use that. + doxygen_xml_dir = doxygen_xml_maybe +else: + # Nothing there, assume it's in LIB_MAPLE_HOME. + doxygen_xml_dir = os.path.join(os.environ['LIB_MAPLE_HOME'], + 'doxygen', 'xml') + +breathe_projects = {'libmaple' : doxygen_xml_dir} + +breathe_default_project = 'libmaple' diff --git a/docs/source/contents.rst b/docs/source/contents.rst new file mode 100644 index 0000000..7be7aec --- /dev/null +++ b/docs/source/contents.rst @@ -0,0 +1,73 @@ +.. _index: + +Contents in Full +================ + +.. _index-usage: + +**Getting Started** + +.. toctree:: + :maxdepth: 2 + + maple-quickstart + maple-ide-install + ide + unix-toolchain + unix-toolchain-linux-setup + unix-toolchain-osx-setup + unix-toolchain-win-setup + whats-new + +.. _index-maple-programming: + +**Programming** + +.. toctree:: + :maxdepth: 2 + + language + libraries + arduino-compatibility + libmaple + bootloader + troubleshooting + FAQ <faq> + arm-gcc + language-index + +.. _index-hardware: + +**Hardware and Peripherals** + +.. toctree:: + :maxdepth: 2 + + stm32 + adc + external-interrupts + fsmc + gpio + i2c + jtag + pwm + spi + timers + systick + usb + usart + +.. _index-boards: + +**Boards** + +.. toctree:: + :maxdepth: 2 + + hardware/maple.rst + hardware/maple-ret6.rst + hardware/maple-mini.rst + hardware/maple-native-beta.rst + +.. TODO [Maple Native] write/include upon finished Native release +.. hardware/maple-native.rst diff --git a/docs/source/epilog.rst b/docs/source/epilog.rst new file mode 100644 index 0000000..b548001 --- /dev/null +++ b/docs/source/epilog.rst @@ -0,0 +1,14 @@ +.. This file automatically gets included at the end of every file, so +.. it's useful for common references, etc. + +.. Common URL references + +.. _forum: http://forums.leaflabs.com +.. _contact: http://leaflabs.com/contact/ +.. _contact us directly: http://leaflabs.com/contact/ +.. _Python: http://python.org/download/ +.. _PySerial: http://pyserial.sourceforge.net/ +.. _OpenMoko: http://openmoko.com/ +.. _Git: http://git-scm.com/ +.. _dfu-util: http://wiki.openmoko.org/wiki/Dfu-util +.. _easy_install: http://packages.python.org/distribute/easy_install.html diff --git a/docs/source/external-interrupts.rst b/docs/source/external-interrupts.rst new file mode 100644 index 0000000..209d5af --- /dev/null +++ b/docs/source/external-interrupts.rst @@ -0,0 +1,68 @@ +.. highlight:: cpp + +.. _external-interrupts: + +External Interrupts +=================== + +External interrupts can be used to make a voltage change on a +:ref:`pin <gpio>` (the pin going from :ref:`LOW <lang-constants-low>` +to :ref:`HIGH <lang-constants-high>`, or vice-versa) to cause a +function to be called. This can be used to avoid checking for changes +on a pin "manually" by waiting in a loop until the pin changes. + +.. _contents: Contents + :local: + +Overview +-------- + +External interrupts are often used to detect when events happen +outside of the Maple. Example events include when a sensor has data +ready to be read, or when a button has been pushed. When such an +event happens, an interrupt is raised, and the Maple stops whatever it +was doing (it is "interrupted"), and reacts to the event by calling a +function (called an *interrupt handler*) which you specify using +:ref:`lang-attachinterrupt`. + +.. _external-interrupts-exti-line: + +Any pin can be used for external interrupts, but there are some +restrictions. At most 16 different external interrupts can be used at +one time. Further, you can't just pick any 16 pins to use. This is +because every pin on the Maple connects to what is called an *EXTI +line*, and only one pin per EXTI line can be used for external +interrupts at a time [#fextisports]_. + +The EXTI Line Pin Map for your board lists which pins connect to which +EXTI lines: + +* :ref:`Maple <maple-exti-map>` +* :ref:`Maple RET6 Edition <maple-ret6-exti-map>` +* :ref:`Maple Mini <maple-mini-exti-map>` +* :ref:`Maple Native Beta <maple-native-b-exti-map>` + +Function Reference +------------------ + +- :ref:`attachInterrupt() <lang-attachinterrupt>` +- :ref:`detachInterrupt() <lang-detachinterrupt>` +- :ref:`libmaple-exti` + +Recommended Reading +------------------- + +* ST manual `RM0008 + <http://www.st.com/web/en/resource/technical/document/reference_manual/CD00171190.pdf>`_ + (PDF), Chapter 9, "General-purpose and alternate-function I/Os", and + Chapter 10, "Interrupts and Events". + +.. rubric:: Footnotes + +.. [#fextisports] The underlying reason for this restriction is that + the external interrupt lines on the STM32 are shared between + :ref:`GPIO ports <gpio-ports>`. There can be only one external + interrupt on each GPIO bit, out of all of the ports. That is, if + PA4 has an external interrupt on it, then PB4 can't have one, too. + Since the GPIO bit numbers only go from 0 to 15, there can only be + 16 external interrupts at a time. diff --git a/docs/source/faq.rst b/docs/source/faq.rst new file mode 100644 index 0000000..bd155ae --- /dev/null +++ b/docs/source/faq.rst @@ -0,0 +1,115 @@ +.. highlight:: cpp + +.. _faq: + +================================== + Frequently Asked Questions (FAQ) +================================== + +.. contents:: Contents + :local: + +.. _faq-atoi: + +Can I use ``atoi()``, ``strol()``, etc.? +---------------------------------------- + +Just ``#include <stdlib.h>``. See :ref:`arm-gcc-libc` for more +information. + +.. _faq-dynamic-memory: + +Can I use ``malloc()``/``new``? +------------------------------- + +For ``malloc()``, just ``#include <stdlib.h>``, and everything should +work fine. Be careful, though! This isn't like C programming on a +PC. You're on the bare metal, and probably shouldn't be using dynamic +memory unless you know what you're doing. + +``new`` should work out of the box (the warning about knowing what +you're doing applies here as well). If you find that ``new`` (or +``new[]``, ``delete``, etc.) is broken in some way, that's a bug; +please let us know in the `forum`_. + +Some information on the heap: on boards with an external SRAM chip +(like Maple Native), the heap is located on external SRAM by default. +For other boards, the heap is located immediately after ``.bss``, and +grows towards the stack. (In all cases, statically allocated +variables and the stack are located on internal SRAM, for performance +reasons). + +.. _faq-flash-tables: + +How do I replace ``PROGMEM``/put data into Flash? +------------------------------------------------- + +See :ref:`this note <arm-gcc-attribute-flash>`. + +How do I write to a pin at high speed? +-------------------------------------- + +Sometimes, :ref:`lang-digitalwrite` just isn't fast enough. If that's +your situation, you should first try using fast GPIO writes using the +low-level :ref:`libmaple-gpio` interface. This FAQ entry explains +how. + +You'll need to look up the :ref:`GPIO port and bit <gpio-ports>` which +correspond to the pin you want to write to. If you don't know what +that means, don't worry. We'll go through an example here. + +Let's say you want to write to pin 4 on the Maple. In order to find +out the port and bit number, take look at the Maple's :ref:`master pin +map <maple-pin-map-master>` next to "D4". You'll see that in the +"GPIO" column, there's "PB5". That's short for "**P**\ ort **B**, bit +**5**". So the GPIO port is "B", and the bit is "5". (If you're not +on the Maple, you can find your board's pin map :ref:`from here +<gpio-pin-maps>`). + +That's all you need to know. Now you can use the function +``gpio_write_bit()`` to quickly write to the pin. The way you call it +is by writing ``gpio_write_bit(GPIO<port>, <bit>, HIGH/LOW)``, where +``<port>`` is the GPIO port, ``<bit>`` is the bit, and ``HIGH`` or +``LOW`` is the level you want to write to the pin. Here's an example +program which writes pin 4 (GPIOB, bit 5) ``HIGH`` and then ``LOW`` +several times in a row each time it :ref:`lang-loop`\ s:: + + /* + Fast pin writing example, for Maple. + + This example works for pin 4 (PB5 on Maple). If you want to + use another pin (or are on another board), just change PIN, + PIN_PORT, and PIN_BIT as described above. + */ + + #define PIN 4 + #define PIN_PORT GPIOB + #define PIN_BIT 5 + + void setup() { + pinMode(PIN, OUTPUT); + } + + void loop() { + gpio_write_bit(PIN_PORT, PIN_BIT, HIGH); + gpio_write_bit(PIN_PORT, PIN_BIT, LOW); + gpio_write_bit(PIN_PORT, PIN_BIT, HIGH); + gpio_write_bit(PIN_PORT, PIN_BIT, LOW); + } + +Now, if you've already tried this and you still can't get enough +speed, there are some threads on the `forum`_ which might help you +squeeze a little extra out of your board. First, a `general summary +<http://forums.leaflabs.com/topic.php?id=860>`_ of other things to +try, with measurements of the speed you'll get. Next, a thread +featuring a `detailed discussion on pin capability +<http://forums.leaflabs.com/topic.php?id=774>`_, with a focus on +writes. And finally, `another thread +<http://forums.leaflabs.com/topic.php?id=895>`_ on the subject which +summarizes a variety of other threads on doing I/O quickly. + +Can I use Maple without Maple IDE? +---------------------------------- + +Yes. See :ref:`unix-toolchain` for the details. + diff --git a/docs/source/fsmc.rst b/docs/source/fsmc.rst new file mode 100644 index 0000000..c8f0125 --- /dev/null +++ b/docs/source/fsmc.rst @@ -0,0 +1,33 @@ +.. _fsmc: + +FSMC +==== + +The Flexible Static Memory Controller (FSMC) is a peripheral which an +be configured to control a variety of external memory chips. + +Normally, any variables in your program will be allocated space in RAM +(notable exceptions are variables marked with ``const`` or +:ref:`__FLASH__ <arm-gcc-attribute-flash>`). Without the FSMC, this +space is limited to the amount that comes built-in to the chip's +*internal* SRAM. + +The addition of the FSMC peripheral allows addtional memory to be +used. For example, it is used on the Maple Native to interface with +the board's built-in external SRAM chip. However, this extra memory +comes at a cost: the FSMC uses a fairly large number of GPIOs. + +The FSMC peripheral is currently only available on the Maple Native. +On that board, we have broken out a wide variety of the FSMC lines, so +that experienced users can add additional external memory chips to +suit their own applications' purposes. + +.. TODO Find some tutorials on SRAM or write one on FSMC, specifically +.. ones that cover: address, data, chip-select etc. pins, memory bank +.. organization + +Recommended Reading +------------------- + +- Wikipedia article on `SRAM <http://en.wikipedia.org/wiki/Static_random-access_memory>`_ +- :ref:`ST RM0008 <maple-native-b-stdocs>` chapter on FSMC. diff --git a/docs/source/gpio.rst b/docs/source/gpio.rst new file mode 100644 index 0000000..caaae3d --- /dev/null +++ b/docs/source/gpio.rst @@ -0,0 +1,106 @@ +.. _gpio: + +GPIO +==== + +Each LeafLabs board comes with ready-to-use General Purpose +Input/Output (GPIO) pins, which are numbered starting from zero. +These numbers are listed on your board's silkscreen, next to where the +pin is broken out to a header. Many pins may additionally be used for +special features or interfacing with other hardware. + +.. contents:: Contents + :local: + +.. _gpio-modes: + +GPIO Modes +---------- + +Each GPIO pin can be configured using :ref:`lang-pinmode` to behave in +a number of ways: as a digital output pin, as an analog input pin, +etc. + +A :ref:`WiringPinMode <lang-pinmode-wiringpinmode>` value specifies +the complete set of possible configurations; not every pin can have +all of these modes. For example, on the Maple, pin 15 may have mode +``INPUT_ANALOG``, but not ``PWM``. See your board's :ref:`pin maps +<gpio-pin-maps>` and its silkscreen for more information on what +functionality is available on each pin. + +Function Reference +------------------ + +- :ref:`lang-pinmode` + +- :ref:`lang-digitalread` + +- :ref:`lang-digitalwrite` + +- :ref:`lang-analogread` + +- :ref:`lang-pwmwrite` (Maple's equivalent to ``analogWrite()``; see + :ref:`lang-analogwrite` for differences from the Arduino version). + +.. _gpio-ports: + +GPIO Ports +---------- + +Normally, you'll interact with pins using just their number (or a +constant like :ref:`BOARD_LED_PIN <lang-board-values-led>` which +stands for a number). However, behind the scenes, the STM32 +microcontroller on your board separates the pins into groups called +*GPIO ports*. Each GPIO port is given a letter, so for example, +there's GPIO port A, port B, and so on\ [#fnumports]_. The pins on a +GPIO port are given *bit numbers*, which go from 0 to 15. In ST's +documentation, a pin is given by the letter "P", followed by its port +letter and bit number. For instance, "PA4" is GPIO port A, bit 4. + +.. _gpio-pin-maps: + +Pin Maps +-------- + +Part of :ref:`Maple IDE's <ide>` job is to convert normal pin numbers +into the corresponding GPIO port and bit when you call functions like +:ref:`lang-pinmode`. It does this using a *pin map*, which lists the +GPIO port and bit for each pin number. The GPIO documentation for +your board includes its pin map, which also lists the other +peripherals by pin number: + +* :ref:`Maple <maple-gpios>` +* :ref:`Maple RET6 Edition <maple-ret6-gpios>` +* :ref:`Maple Mini <maple-mini-gpios>` +* :ref:`Maple Native (Beta) <maple-native-b>` + +.. * :ref:`Maple Native <maple-native-gpios>` + +.. _gpio-5v-tolerant: + +The current and voltage limitations were determined using the STM32 +datasheets. In particular, only some GPIO pins are **5V tolerant**, +which means that applying 5 volts to a pin and reading it as input or +allowing it to drain to ground will not damage that pin. Connecting a +voltage higher than 3.3V to a non-5V tolerant pin may damage your +board. + +.. _gpio-recommended-reading: + +Recommended Reading +------------------- + +* ST Documentation for the STM32F103 series of microcontrollers: + + * `Reference Manual RM0008 + <http://www.st.com/web/en/resource/technical/document/reference_manual/CD00171190.pdf>`_ + (PDF); general, definitive resource for STM32F1 line. + * `Programming Manual PM0056 + <http://www.st.com/st-web-ui/static/active/en/resource/technical/document/programming_manual/CD00228163.pdf>`_ + (PDF); assembly language and register reference. + +.. rubric:: Footnotes + +.. [#fnumports] The total number of GPIO ports depends on what board + you have. For example, Maple Mini has three: ports A, B, and C. + Maple Native has seven: ports A through G. diff --git a/docs/source/hardware/maple-mini.rst b/docs/source/hardware/maple-mini.rst new file mode 100644 index 0000000..c28211d --- /dev/null +++ b/docs/source/hardware/maple-mini.rst @@ -0,0 +1,402 @@ +.. _maple-mini: + +Maple Mini +========== + +This page is a general resource for information specific to the Maple +Mini. The Maple Mini is a smaller version of the Maple that fits on a +breadboard. + +.. contents:: Contents + :local: + +.. TODO [dma.rst] Ref to dma.rst in sequel instead of libmaple-dma + +Technical Specifications +------------------------ + +* MCU: :ref:`STM32F103CBT6 <maple-mini-stdocs>`, a 32-bit ARM Cortex + M3 microprocessor +* Clock Speed: **72 MHz** +* **128 KB Flash** and **20 KB SRAM** +* 34 :ref:`digital I/ pins (GPIOs) <gpio>` +* 12 :ref:`PWM <pwm>` pins at 16 bit resolution +* 9 :ref:`analog input (ADC) <adc>` pins at 12 bit resolution +* 2 :ref:`SPI <spi>` peripherals +* 2 :ref:`I2C <i2c>` peripherals +* 7 Channels of Direct Memory Access (**DMA**) (:ref:`libmaple-dma`) +* 3 :ref:`USART (serial port) <usart>` peripherals +* 1 advanced and 3 general-purpose :ref:`timers <timers>` +* Dedicated :ref:`USB <usb>` port for programming and communications +* :ref:`jtag` +* Nested Vectored Interrupt Controller (NVIC) (including + :ref:`external interrupt <external-interrupts>` on GPIOs) +* Supplies up to 500 mA at 3.3 V, with :ref:`separate 250 mA digital + and analog regulators <maple-mini-adc-bank>` for low-noise analog + performance +* :ref:`Open source, four layer design <maple-mini-hardware>` +* Support for low power, sleep, and standby modes (<500 μA) +* Operating Voltage: 3.3 V +* Input Voltage (recommended): 3 V — 12 V +* Dimensions: 2.02″ × 0.72″ + +.. _maple-mini-powering: + +Powering the Maple Mini +----------------------- + +You can power the Maple Mini via the USB plug or by powering Vin +directly. + +.. warning:: The silkscreen on the Maple Mini suggests it will accept + an input voltage up to 16 V. We recommend applying **no greater + than 12 V**, and potentially even lower depending upon the current + draw requirements of the application. Please see :ref:`Power + Regulation on the Maple Mini <maple-mini-power-regulation>` for + more information. + +.. _maple-mini-power-regulation: + +Power Regulation on the Maple Mini +---------------------------------- + +Power regulation on the Maple is provided by two low dropout linear +voltage regulators. (The part is the MCP1703 from Microchip, in the +SOT-23A package. You can download the datasheet `here +<http://ww1.microchip.com/downloads/en/DeviceDoc/22049a.pdf>`_ ). One +of the regulators supplies power to the digital voltage plane; the +other supplies power to the analog voltage plane. + +These voltage regulators nominally take an input of up to 16V. In +addition, while the maximum continuous output current for the board is +250mA, if you are powering the board off higher voltages the amount +current it can supply goes down, due to the regulators needing to +dissipate the extra power. So if you are powering the board off 12V, +the max current is about 40mA at room temperature. In general (again, +at room temperature) the max power dissipation (PD) for the chip is +about .37W, and output current = PD/(Vin-Vout). For exact max current +calculations, please refer to the datasheet linked above. + +If you are planning to draw a lot of current from the Maple board, it +is necessary to provide input power as close to 3.3V as +possible. Powering the microcontroller circuitry and LEDs on the board +alone takes approximately 30mA, so if you are powering the board with +12V that leaves only 10mA (at best) available for powering any user +circuitry. Attempting to draw more than 10mA runs the risk of shorting +out the power regulators and bricking your board. + +.. _maple-mini-gpios: + +GPIO Information +---------------- + +The Maple Mini features 34 total input/output pins, numbered ``D0`` +through ``D33``. These numbers correspond to the numeric values next +to each header on the Maple Mini's silkscreen. However, some of them +have special uses by default [#fusedpins]_. + +.. _maple-mini-usb-pins: + +Pin ``D23`` is the :ref:`USB <usb>` D+ line, and ``D24`` is the USB D- +line. To use them as GPIOs, your program will need to :ref:`disable +SerialUSB <lang-serialusb-end>` first. Be aware, however, that +disabling SerialUSB means that the :ref:`bootloader <bootloader>` +won't work properly, and you'll need to use +:ref:`troubleshooting-perpetual-bootloader` to make your next upload. + +.. _maple-mini-but: + +Pin ``D32`` is the Mini's :ref:`button pin <lang-board-values-but>`. +It is thus mainly useful as an :ref:`input <lang-pin-levels>`. The +pin will :ref:`read <lang-digitalread>` ``HIGH`` when the :ref:`button +is pressed <lang-isbuttonpressed>`. + +.. _maple-mini-led: + +Pin ``D33`` is the Mini's :ref:`LED pin <lang-board-values-led>`. It +is thus mainly useful as an :ref:`output <lang-pin-levels>`. The LED +will glow when ``HIGH`` is :ref:`written <lang-digitalwrite>` to it. +(It also supports :ref:`pwm`, for finer-grained brightness control). + +.. TODO [0.1.0] silkscreen pictures which expand abbreviations + +.. _maple-mini-pin-map-master: + +Master Pin Map +^^^^^^^^^^^^^^ + +This table shows a summary the available functionality on every GPIO +pin, by peripheral type. The "5 V?" column documents whether or not +the pin is :ref:`5 volt tolerant <gpio-5v-tolerant>`. + +Note that this table is not exhaustive; on some pins, more peripherals +are available than are listed here. + +.. csv-table:: + :header: Pin, :ref:`GPIO <gpio>`, :ref:`ADC <adc>`, :ref:`Timer <timers>`, :ref:`I2C <i2c>`, :ref:`UART <usart>`, :ref:`SPI <spi>`, 5 V? + + D0, PB11, -, -, 2_SDA, 3_RX, -, Yes + D1, PB10, -, -, 2_SCL, 3_TX, -, Yes + D2, PB2, -, -, -, -, -, Yes + D3, PB0, CH8, 3_CH3, -, -, -, - + D4, PA7, CH7, 3_CH2, -, -, 1_MOSI, - + D5, PA6, CH6, 3_CH1, -, -, 1_MISO, - + D6, PA5, CH5, -, -, -, 1_SCK, - + D7, PA4, CH4, -, -, 2_CK, 1_NSS, - + D8, PA3, CH3, 2_CH4, -, 2_RX, -, - + D9, PA2, CH2, 2_CH3, -, 2_TX, -, - + D10, PA1, CH1, 2_CH2, -, 2_RTS, -, - + D11, PA0, CH0, 2_CH1_ETR, -, 2_CTS, -, - + D12, PC15, -, -, -, -, -, - + D13, PC14, -, -, -, -, -, - + D14, PC13, -, -, -, -, -, - + D15, PB7, -, 4_CH2, 1_SDA, -, -, Yes + D16, PB6, -, 4_CH1, 2_SCL, -, -, Yes + D17, PB5, -, -, 1_SMBA, -, -, - + D18, PB4, -, -, -, -, -, Yes + D19, PB3, -, -, -, -, -, Yes + D20, PA15, -, -, -, -, -, Yes + D21, PA14, -, -, -, -, -, Yes + D22, PA13, -, -, -, -, -, Yes + D23, PA12, -, 1_ETR, -, 1_RTS, -, Yes + D24, PA11, -, 1_CH4, -, 1_CTS, -, Yes + D25, PA10, -, 1_CH3, -, 1_RX, -, Yes + D26, PA9, -, 1_CH2, -, 1_TX, -, Yes + D27, PA8, -, 1_CH1, -, 1_CK, -, Yes + D28, PB15, -, -, -, -, 2_MOSI, Yes + D29, PB14, -, -, -, 3_RTS, 2_MISO, Yes + D30, PB13, -, -, -, 3_CTS, 2_SCK, Yes + D31, PB12, -, 1_BKIN, 2_SMBA, 3_CK, 2_NSS, Yes + D32, PB8, -, 4_CH3, -, -, -, Yes + D33, PB1, CH9, 3_CH4, -, -, -, - + +.. _maple-mini-gpio-port-map: + +GPIO Port Pin Map +^^^^^^^^^^^^^^^^^ +The following table shows what pins are associated with each +:ref:`GPIO port <gpio-ports>`. + +.. csv-table:: + :header: GPIOA, GPIOB, GPIOC + + PA0: D11, PB0: D3, PC0: - + PA1: D10, PB1: D33, PC1: - + PA2: D9, PB2: D2, PC2: - + PA3: D8, PB3: D19, PC3: - + PA4: D7, PB4: D18, PC4: - + PA5: D6, PB5: D17, PC5: - + PA6: D5, PB6: D16, PC6: - + PA7: D4, PB7: D15, PC7: - + PA8: D27, PB8: D32, PC8: - + PA9: D26, PB9: -, PC9: - + PA10: D25, PB10: D1, PC10: - + PA11: D24, PB11: D0, PC11: - + PA12: D23, PB12: D31, PC12: - + PA13: D22, PB13: D30, PC13: D14 + PA14: D21, PB14: D29, PC14: D13 + PA15: D20, PB15: D28, PC15: D12 + +.. _maple-mini-timer-map: + +Timer Pin Map +^^^^^^^^^^^^^ + +The following table shows what pins are associated with a particular +timer's capture/compare channels. + +.. csv-table:: + :header: Timer, Ch. 1, Ch. 2, Ch. 3, Ch. 4 + :delim: | + + 1 | D27 | D26 | D25 | D24 + 2 | D11 | D10 | D9 | D8 + 3 | D5 | D4 | D3 | :ref:`D33 <maple-mini-led>` + 4 | D16 | D15 | :ref:`D32 <maple-mini-but>` | + +.. _maple-mini-exti-map: + +EXTI Line Pin Map +^^^^^^^^^^^^^^^^^ + +The following table shows which pins connect to which :ref:`EXTI lines +<external-interrupts-exti-line>`. + +.. list-table:: + :widths: 1 1 + :header-rows: 1 + + * - EXTI Line + - Pins + * - EXTI0 + - D3, D11 + * - EXTI1 + - D10, D33 + * - EXTI2 + - D2, D9 + * - EXTI3 + - D8, D19 + * - EXTI4 + - D7, D18 + * - EXTI5 + - D6, D17 + * - EXTI6 + - D5, D16 + * - EXTI7 + - D4, D15 + * - EXTI8 + - D27, D32 + * - EXTI9 + - D26 + * - EXTI10 + - D1, D25 + * - EXTI11 + - D0, D24 + * - EXTI12 + - D23, D31 + * - EXTI13 + - D14, D22, D30 + * - EXTI14 + - D13, D21, D29 + * - EXTI15 + - D12, D20, D28 + +.. _maple-mini-usart-map: + +USART Pin Map +^^^^^^^^^^^^^ + +The Maple Mini has three serial ports (also known as :ref:`USARTs +<usart>`). They communicate using the pins given in the following +table. + +.. csv-table:: + :header: Serial Port, TX, RX, CK, CTS, RTS + :delim: | + + ``Serial1`` | D26 | D25 | D27 | D24 | D23 + ``Serial2`` | D9 | D8 | D7 | D11 | D10 + ``Serial3`` | D1 | D0 | D31 | D30 | D29 + +.. _maple-mini-adc-bank: + +Low-Noise ADC Pins +^^^^^^^^^^^^^^^^^^ + +Maple Mini has an electrically isolated analog power plane with its +own regulator, and a geometrically isolated ground plane, connected to +the digital plane by an inductor. Its analog input pins, D3 — D11, +are laid out to correspond with these analog planes, and our +measurements indicate that they generally offer low noise ADC +performance. However, analog performance may vary depending upon the +activity of the other GPIOs. Consult the :ref:`Maple Mini hardware +design files <maple-mini-hardware>` for more details. + +.. _maple-mini-board-values: + +Board-Specific Values +--------------------- + +This section lists the Maple Mini's :ref:`board-specific values +<lang-board-values>`. + +- ``CYCLES_PER_MICROSECOND``: 72 +- ``BOARD_BUTTON_PIN``: 32 +- ``BOARD_LED_PIN``: 33 +- ``BOARD_NR_GPIO_PINS``: 34 +- ``BOARD_NR_PWM_PINS``: 12 +- ``boardPWMPins``: 3, 4, 5, 8, 9, 10, 11, 15, 16, 25, 26, 27 +- ``BOARD_NR_ADC_PINS``: 9 +- ``boardADCPins``: 3, 4, 5, 6, 7, 8, 9, 10, 11 +- ``BOARD_NR_USED_PINS``: 4 +- ``boardUsedPins``: ``BOARD_LED_PIN``, ``BOARD_BUTTON_PIN``, 23, 24 + (23 and 24 are used by :ref:`USB <maple-mini-usb-pins>`) +- ``BOARD_NR_USARTS``: 3 +- ``BOARD_USART1_TX_PIN``: 26 +- ``BOARD_USART1_RX_PIN``: 25 +- ``BOARD_USART2_TX_PIN``: 9 +- ``BOARD_USART2_RX_PIN``: 8 +- ``BOARD_USART3_TX_PIN``: 1 +- ``BOARD_USART3_RX_PIN``: 0 +- ``BOARD_NR_SPI``: 2 +- ``BOARD_SPI1_NSS_PIN``: 7 +- ``BOARD_SPI1_MOSI_PIN``: 4 +- ``BOARD_SPI1_MISO_PIN``: 5 +- ``BOARD_SPI1_SCK_PIN``: 6 +- ``BOARD_SPI2_NSS_PIN``: 31 +- ``BOARD_SPI2_MOSI_PIN``: 28 +- ``BOARD_SPI2_MISO_PIN``: 29 +- ``BOARD_SPI2_SCK_PIN``: 30 +- ``BOARD_JTMS_SWDIO_PIN``: 22 +- ``BOARD_JTCK_SWCLK_PIN``: 21 +- ``BOARD_JTDI_PIN``: 20 +- ``BOARD_JTDO_PIN``: 19 +- ``BOARD_NJTRST_PIN``: 18 + +.. _maple-mini-hardware: + +Hardware Design Files +--------------------- + +The hardware schematics and board layout files are available in the +`Maple Mini GitHub repository <https://github.com/leaflabs/maplemini>`_. + +From the GitHub repository main page, you can download the entire +repository by clicking the "Download" button. If you are familiar +with `Git <http://git-scm.com/>`_, you can also clone the repository +at the command line with :: + + $ git clone git://github.com/leaflabs/maplemini.git + +Failure Modes +------------- + +The following known failure modes apply to all Maple boards. The +failure modes aren't design errors, but are easy ways to break or +damage your board permanently. + +* **High voltage on non-tolerant pins**: not all header pins are 5 V + compatible; so e.g. connecting certain serial devices in the wrong + way could over-voltage the pins. The :ref:`pin-mapping master table + <maple-mini-pin-map-master>` details which pins are :ref:`5 + V-tolerant <gpio-5v-tolerant>`. + +Errata +------ + +This section lists known issues and warnings for the Maple Mini Rev 2 +(the first Rev sold to the public). + +.. _maple-mini-vin: + +* **Silkscreen Vin voltage mistake**: The silkscreen on the Maple Mini + falsely indicates that Vin may be supplied with up to 16V. We + recommend an input voltage **no greater than 12V**, and potentially + even lower depending upon the current draw requirements of the + application. Please see :ref:`Power Regulation on the Maple Mini + <maple-mini-power-regulation>` for more information. + + +Recommended Reading +------------------- + +.. _maple-mini-stdocs: + +STMicro documentation for STM32F103CB microcontroller: + +* `Datasheet + <http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/DATASHEET/CD00161566.pdf>`_ + (PDF); covers STM32F103x8, STM32F103xB. +* `Reference Manual RM0008 + <http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/REFERENCE_MANUAL/CD00171190.pdf>`_ + (PDF); definitive resource for peripherals on the STM32F1 line. +* `Programming Manual PM0056 + <http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/PROGRAMMING_MANUAL/CD00228163.pdf>`_ + (PDF); assembly language and register reference. +* `STM32F103CB <http://www.st.com/internet/mcu/product/189782.jsp>`_ + overview page with links to further references. + +.. rubric:: Footnotes + +.. [#fusedpins] See :ref:`boardUsedPins <lang-board-values-used-pins>` + for more information. diff --git a/docs/source/hardware/maple-native-beta.rst b/docs/source/hardware/maple-native-beta.rst new file mode 100644 index 0000000..bdfd216 --- /dev/null +++ b/docs/source/hardware/maple-native-beta.rst @@ -0,0 +1,605 @@ +.. highlight:: sh + +.. _maple-native-b: + +Maple Native β +============== + +This page is a general resource for information specific to the Maple +Native Beta. Since this is a beta release, the information here may +change slightly between now and the final Maple Native release. + +.. contents:: Contents + :local: + +Technical Specifications +------------------------ + +* MCU: `STM32F103ZET6 <maple-native-b-stdocs>`, a 32-bit ARM Cortex M3 + microprocessor. +* Clock Speed: **72 MHz** +* **512 KB Flash**, **64 KB SRAM** (on-chip), **1 MB SRAM** (external) +* 106 :ref:`digital I/O pins <gpio>` +* 17 :ref:`PWM <pwm>` pins at 16 bit resolution +* 21 :ref:`analog input (ADC) <adc>` pins at 12-bit resolution +* 3 :ref:`SPI <spi>` peripherals +* 2 :ref:`I2C <i2c>` peripherals +* 12 Channels of Direct Memory Access (**DMA**) (:ref:`libmaple-dma`) + with 2 DMA controllers +* 3 :ref:`USART (serial port) <usart>` peripherals, 2 **UART** peripherals +* 2 advanced, 4 general-purpose, and 2 basic :ref:`timers <timers>` +* Dedicated :ref:`USB <usb>` port for programming and communications +* :ref:`JTAG <jtag>` +* Nested Vectored Interrupt Controller (NVIC) (including + :ref:`external interrupt <lang-attachinterrupt>` on GPIOs) +* Supplies up to 500 mA at 3.3 V, with :ref:`separate 250 mA digital + and analog regulators <maple-native-b-adc-bank>` for low-noise analog + performance +* :ref:`Open-source, four layer design <maple-native-b-hardware>` +* Support for low power, sleep, and standby modes (<500 μA) +* Operating Voltage: 3.3 V +* Input Voltage (recommended): 3 V — 12 V +* Dimensions: 4″ × 2.1″ + +.. _maple-native-b-powering: + +Powering the Maple Native +------------------------- + +The power source is determined by the header labeled "PWRSEL" on the +silkscreen. The Maple Native may be powered from USB (marked "USB" on +the PWRSEL header), a LiPo battery (marked "BAT"), or one of the two +"Vin" pins (marked "EXT"). Boards are shipped with a jumper on the +USB selector. In order to power it off of an alternative source, +unplug the Maple Native, then move the jumper to the desired selector +before reconnecting power. + +The "Vin" line is available on the pin labeled "Vin" on the vertical +header to the right of the PWRSEL header, as well as on the +unpopulated two-pin connector on the upper left corner of the +board. On this latter connector, polarity was accidentally left +unmarked: the leftmost, round pin should be power, while the square +pin should be ground. + +When powering the Maple Native board from a battery or the Vin lines, +care must be taken not to over-voltage the board. In general, an upper +limit of 12V input is acceptable, but this may vary depending upon the +current draw requirements of the application. Please see :ref:`Power +Regulation on the Maple Native <maple-native-b-power-regulation>` for +more information. + +.. _maple-native-b-power-regulation: + +Power Regulation on the Maple Native +------------------------------------ + +Power regulation on the Maple Native is provided by two low dropout +linear voltage regulators. (The part is the MCP1703 from Microchip, in +the SOT-23A package. You can download the datasheet `here +<http://ww1.microchip.com/downloads/en/DeviceDoc/22049a.pdf>`_). One +of the regulators supplies power to the digital voltage plane; the +other supplies power to the analog voltage plane. + +These voltage regulators nominally take an input of up to 16V. In +addition, while the maximum continuous output current for the board is +250mA, if you are powering the board off higher voltages the current +it can supply goes down, due to the regulators needing to dissipate +the extra power. So if you are powering the board off 12V, the max +current is about 40mA at room temperature. In general (again, at room +temperature) the max power dissipation (PD) for the chip is about +.37W, and output current = PD/(Vin-Vout). For exact max current +calculations, please refer to the datasheet linked above. + +If you are planning to draw a lot of current from the Maple Native +board, it is necessary to provide input power as close to 3.3V as +possible. Powering the microcontroller circuitry and LEDs on the board +alone takes approximately 30mA, so if you are powering the board with +12V that leaves only 10mA (at best) available for powering any user +circuitry. Attempting to draw more than 10mA runs the risk of shorting +out the power regulators and bricking your board. + +Using the Built-in Battery Charger +---------------------------------- + +Maple Native includes a built-in LiPo battery charger. In order to +use it, put a jumper across the CHRG selector on the PWRSEL header and +across the USB, or EXT selectors, depending on whether you're charging +the battery via USB cable or Vin, respectively. The LED labeled CHRG +will light up while the battery is being charged. When the battery is +finished charging, the LED labeled DONE will light up. + +.. _maple-native-b-gpios: + +GPIO Information +---------------- + +The Maple Native features 106 total input/output pins, numbered ``D0`` +through ``D105``. In most cases, these numbers correspond to the +numeric values next to each header on the Maple Native's silkscreen. +However, pins ``D101`` through ``D105`` are broken out to the +:ref:`JTAG <jtag>` header, and are not numbered on the silkscreen. In +addition, some other pins have other uses by default [#fusedpins]_. + +.. _maple-native-b-but: + +Pin ``D6`` is the Native's :ref:`button pin <lang-board-values-but>`. +It is thus mainly useful as an :ref:`input <lang-pin-levels>`. The +pin will :ref:`read <lang-digitalread>` ``HIGH`` when the :ref:`button +is pressed <lang-isbuttonpressed>`. + +.. _maple-native-b-led: + +Pin ``D22`` is the Native's :ref:`LED pin <lang-board-values-led>`. +It is thus mainly useful as an :ref:`output <lang-pin-levels>`. The +LED will glow when ``HIGH`` is :ref:`written <lang-digitalwrite>` to +it. + +.. _maple-native-b-fsmc: + +Many of the pins on the right header (pins ``D56`` through ``D100``, +the header is labeled :ref:`"FSMC" <fsmc>` on the silkscreen) are +connected to the SRAM chip. Using these pins as GPIOs may render the +memory chip useless, which can cause your program to crash. For this +reason, we don't recommend that you use these pins unless you know +what you are doing. The following pins on the right header are not +connected to the SRAM and may be used with impunity: ``D57``, ``D60``, +``D63``, ``D66``, ``D69``, ``D72``, ``D75``, ``D80``, ``D83``. + +.. _maple-native-b-jtag: + +Pins ``D101`` through ``D105`` are connected to the pads on the +:ref:`JTAG <jtag>` header. In order to use them as GPIOs, you must +first disable the Maple Native's debug ports. You can do this by +calling :ref:`lang-disabledebugports`. (Note that this means you +won't be able to use JTAG or SW-Debug to debug your program). + +.. TODO [0.1.0] silkscreen pictures + +.. _maple-native-b-pin-map-master: + +Master Pin Map +^^^^^^^^^^^^^^ + +This table shows a summary the available functionality on every GPIO +pin, by peripheral type. The "5 V?" column documents whether or not +the pin is :ref:`5 volt tolerant <gpio-5v-tolerant>`. + +Note that this table is not exhaustive; on some pins, more peripherals +are available than are listed here. + +**Top header:** + +.. csv-table:: + :header: Pin, :ref:`GPIO <gpio>`, :ref:`ADC <adc>`, :ref:`Timer <timers>`, :ref:`I2C <i2c>`, :ref:`UART <usart>`, :ref:`SPI <spi>`, 5 V? + + D0, PB10, -, -, 2_SCL, 3_TX, -, Yes + D1, PB11, -, -, 2_SDA, 3_RX, -, Yes + D2, PB12, -, 1_BKIN, 2_SMBA, 3_CK, 2_NSS, Yes + D3, PB13, -, -, -, 3_CTS, 2_SCK, Yes + D4, PB14, -, -, -, 3_RTS, 2_MISO, Yes + D5, PB15, -, -, -, -, 2_MOSI, Yes + D6, PG15, -, -, -, -, -, Yes + D7, PC0, 1_CH10, -, -, -, -, - + D8, PC1, 1_CH11, -, -, -, -, - + D9, PC2, 1_CH12, -, -, -, -, - + D10, PC3, 1_CH13, -, -, -, -, - + D11, PC4, 1_CH14, -, -, -, -, - + D12, PC5, 1_CH15, -, -, -, -, - + D13, PC6, -, 8_CH1, -, -, -, Yes + D14, PC7, -, 8_CH2, -, -, -, Yes + D15, PC8, -, 8_CH3, -, -, -, Yes + D16, PC9, -, 8_CH4, -, -, -, Yes + D17, PC10, -, -, -, 4_TX, -, Yes + D18, PC11, -, -, -, 4_RX, -, Yes + D19, PC12, -, -, -, 5_TX, -, Yes + D20, PC13, -, -, -, -, -, - + D21, PC14, -, -, -, -, -, - + D22, PC15, -, -, -, -, -, - + D23, PA8, -, 1_CH1, -, 1_CK, -, Yes + D24, PA9, -, 1_CH2, -, 1_TX, -, Yes + D25, PA10, -, 1_CH3, -, 1_RX, -, Yes + D26, PB9, -, 4_CH4, -, -, -, Yes + +**Bottom header:** + +.. note:: ``D48``, ``D49``, ``D50``, ``D51`` are also connected to + Timer 2 channels 1, 2, 3, and 4, respectively. + +.. csv-table:: + :header: Pin, :ref:`GPIO <gpio>`, :ref:`ADC <adc>`, :ref:`Timer <timers>`, :ref:`I2C <i2c>`, :ref:`UART <usart>`, :ref:`SPI <spi>`, 5 V? + + D27, PD2, -, 3_ETR, -, 5_RX, -, Yes + D28, PD3, -, -, -, -, -, Yes + D29, PD6, -, -, -, -, -, Yes + D30, PG11, -, -, -, -, -, Yes + D31, PG12, -, -, -, -, -, Yes + D32, PG13, -, -, -, -, -, Yes + D33, PG14, -, -, -, -, -, Yes + D34, PG8, -, -, -, -, -, Yes + D35, PG7, -, -, -, -, -, Yes + D36, PG6, -, -, -, -, -, Yes + D37, PB5, -, -, 1_SMBA, -, 3_MOSI, - + D38, PB6, -, 4_CH1, 1_SCL, -, -, Yes + D39, PB7, -, 4_CH2, 1_SDA, -, -, Yes + D40, PF11, -, -, -, -, -, Yes + D41, PF6, 3_CH4, -, -, -, -, - + D42, PF7, 3_CH5, -, -, -, -, - + D43, PF8, 3_CH6, -, -, -, -, - + D44, PF9, 3_CH7, -, -, -, -, - + D45, PF10, 3_CH8, -, -, -, -, - + D46, PB1, 1_CH9, 3_CH4, -, -, -, - + D47, PB0, 1_CH8, 3_CH3, -, -, -, - + D48, PA0, 1_CH0, 5_CH1, -, 2_CTS, -, - + D49, PA1, 1_CH1, 5_CH2, -, 2_RTS, -, - + D50, PA2, 1_CH2, 5_CH3, -, 2_TX, -, - + D51, PA3, 1_CH3, 5_CH4, -, 2_RX, -, - + D52, PA4, 1_CH4, -, -, 2_CK, 1_NSS, - + D53, PA5, 1_CH5, -, -, -, 1_SCK, - + D54, PA6, 1_CH6, 3_CH1, -, -, 1_MISO, - + D55, PA7, 1_CH7, 3_CH2, -, -, 1_MOSI, - + +.. _maple-native-b-fsmc-map: + +**Right (FSMC) header** + +All of the following pins are 5V-tolerant. Note that in the "FSMC" +column below, entries with a "Dn" value (D0, D1, etc.) don't refer to +pins; they refer to FSMC data lines. See :ref:`RM0008 +<maple-native-b-stdocs>` for more information. + +.. warning:: Many of the pins on this header are used by the Maple + Native's SRAM chip. Don't use them as GPIOs unless you know what + you're doing, or your program may crash. :ref:`See above + <maple-native-b-fsmc>` for more information. + +.. csv-table:: + :header: Pin, :ref:`GPIO <gpio>`, :ref:`FSMC <fsmc>` + + D56, PF0, A0 + D57, PD11, A16 + D58, P14, D0 + D59, PF1, A1 + D60, PD12, A17 + D61, PD15, D1 + D62, PF2, A2 + D63, PD13, A18 + D64, PD0, D2 + D65, PF3, A3 + D66, PE3, A19 + D67, PD1, D3 + D68, PF4, A4 + D69, PE4, A20 + D70, PE7, D4 + D71, PF5, A5 + D72, PE5, A21 + D73, PE8, D8 + D74, PF12, A6 + D75, PE6, A22 + D76, PE9, D6 + D77, PF13, A7 + D78, PE10, D7 + D79, PF14, A8 + D80, PG9, NE2/NCE3 + D81, PE11, D8 + D82, PF15, A9 + D83, PG10, NCE4_1/NE3/NCE4_2 + D84, PE12, D9 + D85, PG0, A10 + D86, PD5, NWE + D87, PE13, D10 + D88, PG1, A11 + D89, PD4, NOE + D90, PE14, D11 + D91, PG2, A12 + D92, PE1, NBL1 + D93, PE15, D12 + D94, PG3, A13 + D95, PE0, NBL0 + D96, PD8, D13 + D97, PG4, A14 + D98, PD9, D14 + D99, PG5, A15 + D100, PD10, D15 + +**JTAG header pins** + +.. note:: See :ref:`above <maple-native-b-jtag>` for more information on + these pins. + +.. csv-table:: + :header: Pin, :ref:`GPIO <gpio>`, :ref:`SPI <spi>`, 5 V? + + D101, PA13, -, Yes + D102, PA14, -, Yes + D103, PA15, 3_NSS, Yes + D104, PB3, 3_SCK, Yes + D105, PB4, 3_MISO, Yes + +.. _maple-native-b-gpio-port-map: + +GPIO Port Pin Map +^^^^^^^^^^^^^^^^^ + +The following tables show what pins are associated with each +:ref:`GPIO port <gpio-ports>`. + +.. csv-table:: + :header: GPIOA, GPIOB, GPIOC, GPIOD + + PA0: D48, PB0: D47, PC0: D7, PD0: D64 + PA1: D49, PB1: D46, PC1: D8, PD1: D67 + PA2: D50, PB2: -, PC2: D9, PD2: D27 + PA3: D51, PB3: D104, PC3: D10, PD3: D28 + PA4: D52, PB4: D105, PC4: D11, PD4: D89 + PA5: D53, PB5: D37, PC5: D12, PD5: D86 + PA6: D54, PB6: D38, PC6: D13, PD6: D29 + PA7: D55, PB7: D39, PC7: D14, PD7: - + PA8: D23, PB8: -, PC8: D15, PD8: D96 + PA9: D24, PB9: D26, PC9: D16, PD9: D98 + PA10: D25, PB10: D0, PC10: D17, PD10: D100 + PA11: -, PB11: D1, PC11: D18, PD11: D57 + PA12: -, PB12: D2, PC12: D19, PD12: D60 + PA13: D101, PB13: D3, PC13: D20, PD13: D63 + PA14: D102, PB14: D4, PC14: D21, PD14: D58 + +.. csv-table:: + :header: GPIOE, GPIOF, GPIOG + + PE0: D95, PF0: D56, PG0: D85 + PE1: D92, PF1: D59, PG1: D88 + PE2: - PF2: D62, PG2: D91, + PE3: D66, PF3: D65, PG3: D94 + PE4: D69, PF4: D68, PG4: D97 + PE5: D72, PF5: D71, PG5: D99 + PE6: D75, PF6: D41, PG6: D36 + PE7: D70, PF7: D42, PG7: D35 + PE8: D73, PF8: D43, PG8: D34 + PE9: D76, PF9: D44, PG9: D80 + PE10: D78, PF10: D45, PG10: D83 + PE11: D81, PF11: D40, PG11: D30 + PE12: D84, PF12: D74, PG12: D31 + PE13: D87, PF13: D77, PG13: D32 + PE14: D90, PF14: D79, PG14: D33 + +.. _maple-native-b-timer-map: + +Timer Pin Map +^^^^^^^^^^^^^ + +The following table shows what pins are associated with a particular +timer's capture/compare channels. + +There is no mistake between timers 2 and 5. They really do share +those pins. If you like, you can remap some of the timer 2 channels +to get extra PWM pins; see :ref:`afio_remap() (in gpio.h) +<gpio-h-afio-remap>`. + +.. csv-table:: + :header: Timer, Ch. 1, Ch. 2, Ch. 3, Ch. 4 + :delim: | + + 1 | D23 | D24 | D25 | + 2 | D48 | D49 | D50 | D51 + 3 | D54 | D55 | D47 | D46 + 4 | D38 | D39 | | D26 + 5 | D48 | D49 | D50 | D51 + 8 | D13 | D14 | D15 | D16 + +.. _maple-native-b-exti-map: + +EXTI Line Pin Map +^^^^^^^^^^^^^^^^^ + +The following table shows which pins connect to which :ref:`EXTI lines +<external-interrupts-exti-line>`. + +.. list-table:: + :widths: 1 3 + :header-rows: 1 + + * - EXTI Line + - Pins + * - EXTI0 + - D7, D47, D48, D56, D64, D85, D95 + * - EXTI1 + - D8, D46, D49, D59, D67, D88, D92 + * - EXTI2 + - D9, D27, D50, D62, D91 + * - EXTI3 + - D10, D28, D51, D65, D66, D94, D104 + * - EXTI4 + - D11, D52, D68, D69, D89, D97, D105 + * - EXTI5 + - D12, D37, D53, D71, D72, D86, D99 + * - EXTI6 + - D13, D29, D36, D38, D41, D54, D75 + * - EXTI7 + - D14, D35, D39, D42, D55, D70 + * - EXTI8 + - D15, D23, D34, D43, D73, D96 + * - EXTI9 + - D16, D24, D26, D44, D76, D80, D98 + * - EXTI10 + - D0, D17, D25, D45, D78, D83, D100 + * - EXTI11 + - D1, D18, D30, D40, D57, D81 + * - EXTI12 + - D2, D19, D31, D60, D74, D84 + * - EXTI13 + - D3, D20, D32, D63, D77, D87, D101 + * - EXTI14 + - D4, D21, D33, D58, D79, D90, D102 + * - EXTI15 + - D5, D6, D22, D61, D82, D93, D103 + +.. _maple-native-b-usart-map: + +USART Pin Map +^^^^^^^^^^^^^ + +The Maple Native has 3 :ref:`USART <usart>` serial ports. They +communicate using the pins given in the following table. + +.. csv-table:: + :header: Serial port, TX, RX, CK, CTS, RTS + :delim: | + + ``Serial1`` | D24 | D25 | D23 | | + ``Serial2`` | D50 | D51 | D52 | D48 | D49 + ``Serial3`` | D0 | D1 | D2 | D3 | D4 + +The Maple Native also has 2 UART serial ports. Unlike USARTS, these +only communicate asynchronously, and thus only have TX and RX pins. +These are given in the following table. + +.. csv-table:: + :header: Serial port, TX, RX + :delim: | + + ``Serial4`` | D17 | D18 + ``Serial5`` | D19 | D27 + +.. _maple-native-b-adc-bank: + +Low-Noise ADC Pins +^^^^^^^^^^^^^^^^^^ + +There are fifteen pins at the bottom right of the board (``D41`` — +``D55``) that generally offer lower-noise ADC performance than other +pins on the board. If you're concerned about getting good ADC +readings, we recommend using one of these pins to take your +measurements. + +Maple Native has an electrically isolated analog power plane with its +own regulator, and a geometrically isolated ground plane. Analog input +pins D41 — D55 are laid out to correspond with these analog planes, +and our measurements indicate that they generally ofer low noise ADC +performance. However, analog performance may vary depending upon the +activity of other GPIOs. In particular, using PWM on any of pins +``D46`` — ``D51``, ``D54``, and ``D55`` may cause digital noise. +Consult the :ref:`Maple Native beta hardware design files +<maple-native-b-hardware>` for more details. + +.. _maple-native-b-board-values: + +Board-Specific Values +--------------------- + +This section lists the Maple Native's :ref:`board-specific values +<lang-board-values>`. + +- ``CYCLES_PER_MICROSECOND``: 72 +- ``BOARD_BUTTON_PIN``: 6 +- ``BOARD_LED_PIN``: 22 +- ``BOARD_NR_GPIO_PINS``: 106 +- ``BOARD_NR_PWM_PINS``: 18 +- ``boardPWMPins``: 13, 14, 15, 16, 23, 24, 25, 26, 38, 39, 46, 47, + 48, 49, 50, 51, 54, 55 +- ``BOARD_NR_ADC_PINS``: 21 +- ``boardADCPins``: 7, 8, 9, 10, 11, 12, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55 +- ``BOARD_NR_USED_PINS``: 43 +- ``boardUsedPins``: ``BOARD_LED_PIN``, ``BOARD_BUTTON_PIN``, + ``BOARD_JTMS_SWDIO_PIN``, ``BOARD_JTCK_SWCLK_PIN``, + ``BOARD_JTDI_PIN``, ``BOARD_JTDO_PIN``, ``BOARD_NJTRST_PIN``, and + all pins on FSMC header except those mentioned :ref:`above + <maple-native-b-fsmc>`. +- ``BOARD_NR_USARTS``: 5 +- ``BOARD_USART1_TX_PIN``: 24 +- ``BOARD_USART1_RX_PIN``: 25 +- ``BOARD_USART2_TX_PIN``: 50 +- ``BOARD_USART2_RX_PIN``: 51 +- ``BOARD_USART3_TX_PIN``: 0 +- ``BOARD_USART3_RX_PIN``: 1 +- ``BOARD_UART4_TX_PIN``: 17 +- ``BOARD_UART4_RX_PIN``: 18 +- ``BOARD_UART5_TX_PIN``: 19 +- ``BOARD_UART5_RX_PIN``: 27 +- ``BOARD_NR_SPI``: 3 +- ``BOARD_SPI1_NSS_PIN``: 52 +- ``BOARD_SPI1_MOSI_PIN``: 55 +- ``BOARD_SPI1_MISO_PIN``: 54 +- ``BOARD_SPI1_SCK_PIN``: 53 +- ``BOARD_SPI2_NSS_PIN``: 2 +- ``BOARD_SPI2_MOSI_PIN``: 5 +- ``BOARD_SPI2_MISO_PIN``: 4 +- ``BOARD_SPI2_SCK_PIN``: 3 +- ``BOARD_SPI3_NSS_PIN``: 103 (on :ref:`JTAG header <maple-native-b-jtag>`) +- ``BOARD_SPI3_MOSI_PIN``: 37 +- ``BOARD_SPI3_MISO_PIN``: 105 (JTAG header) +- ``BOARD_SPI3_SCK_PIN``: 104 (JTAG header) +- ``BOARD_JTMS_SWDIO_PIN``: :ref:`103 <maple-native-b-jtag>` +- ``BOARD_JTCK_SWCLK_PIN``: 102 +- ``BOARD_JTDI_PIN``: 103 +- ``BOARD_JTDO_PIN``: 104 +- ``BOARD_NJTRST_PIN``: 105 + +.. _maple-native-b-hardware: + +Hardware Design Files +^^^^^^^^^^^^^^^^^^^^^ + +The hardware schematics and board layout files are available in the +`Maple Native GitHub repository +<https://github.com/leaflabs/maplenative/>`_. Download the `beta +version's hardware design files +<https://github.com/leaflabs/maplenative/tree/beta>`_ (ZIP format). + +If you're familiar with Git, you can clone the entire repository and +checkout the commit tagged "beta" using the following:: + + $ git clone git://github.com/leaflabs/maplenative.git + $ git checkout beta + +Failure Modes +------------- + +The following known failure modes apply to the Maple Native Beta. The +failure modes aren't design errors, but are easy ways to break or +damage your board permanently. + +* **Reversing Vin and GND**: when powering the Maple Native Beta via + the Vin and ground (GND) pins at the top left of the board, it is + possible to carelessly cause a short or switch the connections, + applying the high voltage to GND and ground to Vin. + + If this happens, you will reverse bias the diode beneath these pins, + most likely damaging it. This may cause excess voltage to + subsequently be delivered to the board once the reversed pins are + connected properly. + +Errata +------ + +This section lists known issues and warnings for the Maple Native +Beta. + +* **PWM on pin 39**: PWM on pin 39 appears to be nonfunctional. We + are looking into this issue. + +* **VREF is nonfunctional**: Due to a routing error, VREF is + permanently tied to 3.3V at VAA. + +Recommended Reading +------------------- + +.. _maple-native-b-stdocs: + +STMicro documentation for STM32F103ZE microcontroller: + +* `Datasheet + <http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/DATASHEET/CD00191185.pdf>`_ + (PDF); covers STM32F103xC, STM3F103xD, STM32F103xE. +* `Reference Manual RM0008 + <http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/REFERENCE_MANUAL/CD00171190.pdf>`_ + (PDF); definitive resource for peripherals on the STM32F1 line. +* `Programming Manual PM0056 + <http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/PROGRAMMING_MANUAL/CD00228163.pdf>`_ + (PDF); assembly language and register reference. +* `STM32F103RE <http://www.st.com/internet/mcu/product/164485.jsp>`_ + overview page with links to further references. + +.. rubric:: Footnotes + +.. [#fusedpins] See :ref:`boardUsedPins <lang-board-values-used-pins>` + for more information. diff --git a/docs/source/hardware/maple-native.rst b/docs/source/hardware/maple-native.rst new file mode 100644 index 0000000..79115fc --- /dev/null +++ b/docs/source/hardware/maple-native.rst @@ -0,0 +1,6 @@ +.. _hardware-maple-native: + +Maple Native +============ + +Stub. diff --git a/docs/source/hardware/maple-ret6.rst b/docs/source/hardware/maple-ret6.rst new file mode 100644 index 0000000..3d2d037 --- /dev/null +++ b/docs/source/hardware/maple-ret6.rst @@ -0,0 +1,466 @@ +.. highlight:: sh + +.. _maple-ret6: + +Maple RET6 Edition +================== + +This page is a general resource for information specific to the Maple +RET6 Edition. The Maple RET6 Edition is a "beta" board released as a +simple way to get a more powerful chip (the STM32F103\ **RET6**, hence +the name) than the one on the base Maple (the STM32F103\ **RBT6**) in +the hands of Maple developers. + +.. contents:: Contents + :local: + +.. TODO [dma.rst] Ref to source/dma.rst in sequel instead of libmaple-dma +.. TODO [dac.rst] Ref to source/dac.rst in sequel instead of libmaple-dac +.. TODO [nvic.rst] Ref to source/nvic.rst in sequel + +Technical Specifications +------------------------ + +* MCU: :ref:`STM32F103RET6 <maple-ret6-stdocs>`, a 32-bit ARM Cortex + M3 microprocessor +* Clock Speed: **72 MHz** +* **512 KB Flash** and **64 KB SRAM** +* 43 :ref:`digital I/O pins (GPIOs) <gpio>` +* 18 :ref:`PWM <pwm>` pins at 16 bit resolution +* 15 :ref:`analog input (ADC) <adc>` pins at 12 bit resolution +* Built-in, 2 channel **DAC** at 12 bit resolution (:ref:`libmaple-dac`). +* 2 :ref:`SPI <spi>` peripherals with **I2S** support +* 2 :ref:`I2C <i2c>` peripherals +* 12 Channels of Direct Memory Access (**DMA**) (:ref:`libmaple-dma`) + with 2 DMA controllers +* 3 :ref:`USART (serial port) <usart>` peripherals +* 2 advanced, 4 general-purpose, and 2 basic :ref:`timers <timers>` +* Dedicated :ref:`USB <usb>` port for programming and communications +* :ref:`JTAG <jtag>` +* Nested Vectored Interrupt Controller (NVIC) (including + :ref:`external interrupt <lang-attachinterrupt>` on GPIOs) +* Supplies up to 500 mA at 3.3 V, with :ref:`separate 250 mA digital + and analog regulators <maple-ret6-adc-bank>` for low-noise analog + performance +* :ref:`Open-source, four layer design <maple-ret6-hardware>` +* Support for low power, sleep, and standby modes (<500 μA) +* Operating Voltage: 3.3 V +* Input Voltage (recommended): 4 V — 12 V +* Dimensions are 2.05″ × 2.1″ + +.. _maple-ret6-powering: + +Powering the Maple RET6 Edition +------------------------------- + +The Maple RET6 Edition is powered in the :ref:`same way as the +standard Maple <maple-powering>`. + +.. warning:: The RET6 Edition silkscreen falsely indicates that the + barrel jack accepts up to 18 V. We recommend a barrel jack input + voltage **no greater than 12V**, and potentially even lower + depending upon the current draw requirements of the + application. The same goes for powering off LiPo batteries. + + Please see :ref:`Power Regulation on the Maple + <maple-power-regulation>` for more information. + +.. _maple-ret6power-regulation: + +Power Regulation on the Maple RET6 +---------------------------------- + +Power regulation on the Maple RET6 works in the :ref:`same way as the +standard Maple <maple-power-regulation>`. + +Using the Built-in Battery Charger +---------------------------------- + +The RET6 Edition has a built-in LiPo battery charger. In order to use +it, put a jumper across the CHRG header on the power selection header +and across the USB, or EXT selectors, depending on whether you're +charging the battery via USB cable or barrel jack connector. The LED +labeled CHRG will light up while the battery is being charged. When +the battery is finished charging, the LED labeled DONE will light up. + +.. _maple-ret6-gpios: + +GPIO Information +---------------- + +The RET6 Edition features 38 ready-to-use general purpose input/output +(see :ref:`gpio`) pins for digital input/output, numbered ``D0`` +through ``D37``. These numbers correspond to the numeric values next +to each header on the Maple silkscreen. + +.. _maple-ret6-but: + +Pin ``D38`` is the board's :ref:`button pin <lang-board-values-but>`. +It is thus mainly useful as an :ref:`input <lang-pin-levels>`. The +pin will :ref:`read <lang-digitalread>` ``HIGH`` when the :ref:`button +is pressed <lang-isbuttonpressed>`. + +More GPIOs (numbered ``D39``\ --``D42`` on the back of the RET6 +Edition's silkscreen) are available if you use the +:ref:`lang-disabledebugports` function; see the :ref:`board-specific +debug pin constants <lang-board-values-debug>` for more information. +(See :ref:`this erratum <maple-ret6-nrst-pb4>` for information about +the pin numbered ``43`` on the silkscreen). + +.. TODO [0.1.0] silkscreen pictures which expand abbreviations + +.. _maple-ret6-pin-map-master: + +Master Pin Map +^^^^^^^^^^^^^^ + +This table shows a summary of the available functionality on every +GPIO pin, by peripheral type. The "5 V?" column documents whether or +not the pin is :ref:`5 volt tolerant <gpio-5v-tolerant>`. + +Note that this table is not exhaustive; on some pins, more peripherals +are available than are listed here. + +.. csv-table:: + :header: Pin, :ref:`GPIO <gpio>`, :ref:`ADC <adc>`, :ref:`Timer <timers>`, :ref:`I2C <i2c>`, :ref:`UART/USART <usart>`, :ref:`SPI <spi>`, 5 V? + + D0, PA3, CH3, 2_CH4, -, 2_RX, -, - + D1, PA2, CH2, 2_CH3, -, 2_TX, -, - + D2, PA0, CH0, 2_CH1_ETR, -, 2_CTS, -, - + D3, PA1, CH1, 2_CH2, -, 2_RTS, -, - + D4, PB5, -, -, 1_SMBA, -, 3_MOSI, - + D5, PB6, -, 4_CH1, 1_SCL, -, -, Yes + D6, PA8, -, 1_CH1, -, 1_CK, -, Yes + D7, PA9, -, 1_CH2, -, 1_TX, -, Yes + D8, PA10, -, 1_CH3, -, 1_RX, -, Yes + D9, PB7, -, 4_CH2, 1_SDA, -, -, Yes + D10, PA4, CH4, -, -, 2_CK, 1_NSS, - + D11, PA7, CH7, 3_CH2, -, -, 1_MOSI, - + D12, PA6, CH6, 3_CH1, -, -, 1_MISO, - + D13, PA5, CH5, -, -, -, 1_SCK, - + D14, PB8, -, 4_CH3, -, -, -, Yes + D15, PC0, CH10, -, -, -, -, - + D16, PC1, CH11, -, -, -, -, - + D17, PC2, CH12, -, -, -, -, - + D18, PC3, CH13, -, -, -, -, - + D19, PC4, CH14, -, -, -, -, - + D20, PC5, CH15, -, -, -, -, - + D21, PC13, -, -, -, -, -, - + D22, PC14, -, -, -, -, -, - + D23, PC15, -, -, -, -, -, - + D24, PB9, -, 4_CH4, -, -, -, Yes + D25, PD2, -, 3_ETR, -, -, 5_RX, Yes + D26, PC10, -, -, -, -, 4_TX, Yes + D27, PB0, CH8, 3_CH3, -, -, -, - + D28, PB1, CH9, 3_CH4, -, -, -, - + D29, PB10, -, -, 2_SCL, 3_TX, -, Yes + D30, PB11, -, -, 2_SDA, 3_RX, -, Yes + D31, PB12, -, 1_BKIN, 2_SMBA, 3_CK, 2_NSS, Yes + D32, PB13, -, 1_CH1N, -, 3_CTS, 2_SCK, Yes + D33, PB14, -, 1_CH2N, -, 3_RTS, 2_MISO, Yes + D34, PB15, -, 1_CH3N, -, -, 2_MOSI, Yes + D35, PC6, -, 8_CH1, -, -, -, Yes + D36, PC7, -, 8_CH2, -, -, -, Yes + D37, PC8, -, 8_CH3, -, -, -, Yes + D38, PC9, -, 8_CH4, -, -, -, Yes + D39, PA13, -, -, -, -, -, Yes + D40, PA14, -, -, -, -, -, Yes + D41, PA15, -, -, -, -, 3_NSS, Yes + D42, PB3, -, -, -, -, 3_SCK, Yes + +.. _maple-ret6-gpio-port-map: + +GPIO Port Pin Map +^^^^^^^^^^^^^^^^^ + +The following table shows what pins are associated with each +:ref:`GPIO port <gpio-ports>`. + +.. csv-table:: + :header: GPIOA, GPIOB, GPIOC + + PA0: D2, PB0: D27, PC0: D15 + PA1: D3, PB1: D28, PC1: D16 + PA2: D1, PB2: -, PC2: D17 + PA3: D0, PB3: D42, PC3: D18 + PA4: D10, PB4: D43, PC4: D19 + PA5: D13, PB5: D4, PC5: D20 + PA6: D12, PB6: D5, PC6: D35 + PA7: D11, PB7: D9, PC7: D36 + PA8: D6, PB8: D14, PC8: D37 + PA9: D7, PB9: D24, PC9: D38 + PA10: D8, PB10: D29, PC10: D26 + PA11: -, PB11: D30, PC11: - + PA12: -, PB12: D31, PC12: - + PA13: D39, PB13: D32, PC13: D21 + PA14: D40, PB14: D33, PC14: D22 + PA15: D41, PB15: D34, PC15: D23 + +.. _maple-ret6-timer-map: + +Timer Pin Map +^^^^^^^^^^^^^ + +The following table shows what pins are associated with a particular +timer's capture/compare channels. Note that timer 5's channels share +pins with timer 2 (e.g., timer 5 channel 1 is also available on D2, +channel 2 on D3, etc.). + +.. csv-table:: + :header: Timer, Ch. 1, Ch. 2, Ch. 3, Ch. 4 + :delim: | + + 1 | D6 | D7 | D8 | - + 2 | D2 | D3 | D1 | D0 + 3 | D12 | D11 | D27 | D28 + 4 | D5 | D9 | D14 | D24 + 8 | D35 | D36 | D37 | :ref:`D38 <maple-ret6-but>` + +.. _maple-ret6-exti-map: + +EXTI Line Pin Map +^^^^^^^^^^^^^^^^^ + +The following table shows which pins connect to which :ref:`EXTI lines +<external-interrupts-exti-line>` on the Maple RET6 Edition. + +.. list-table:: + :widths: 1 1 + :header-rows: 1 + + * - EXTI Line + - Pins + * - EXTI0 + - D2, D15, D27 + * - EXTI1 + - D3, D16, D28 + * - EXTI2 + - D1, D17, D25 + * - EXTI3 + - D0, D18, D42 + * - EXTI4 + - D10, D19 + * - EXTI5 + - D4, D13, D20 + * - EXTI6 + - D5, D12, D35 + * - EXTI7 + - D9, D11, D36 + * - EXTI8 + - D6, D14, D37 + * - EXTI9 + - D7, D24, D38 + * - EXTI10 + - D8, D26, D29 + * - EXTI11 + - D30 + * - EXTI12 + - D31 + * - EXTI13 + - D21, D32, D39 + * - EXTI14 + - D22, D33, D40 + * - EXTI15 + - D23, D34, D41 + +.. _maple-ret6-usart-map: + +USART Pin Map +^^^^^^^^^^^^^ + +The Maple RET6 Edition has three serial ports whose pins are broken +out to headers (also known as :ref:`USARTs <usart>`). They communicate +using the pins given in the following table. + +.. csv-table:: + :header: Serial Port, TX, RX, CK, CTS, RTS + :delim: | + + ``Serial1`` | D7 | D8 | D6 | | + ``Serial2`` | D1 | D0 | D10 | D2 | D3 + ``Serial3`` | D29 | D30 | D31 | D32 | D33 + +Unfortunately, :ref:`UART4 and UART5 aren't completely available +<maple-ret6-uarts>`. + +.. _maple-ret6-adc-bank: + +Low-Noise ADC Pins +^^^^^^^^^^^^^^^^^^ + +The six pins at the bottom right of the board (D15—D20) generally +offer lower-noise ADC performance than other pins on the board. If +you’re concerned about getting good ADC readings, we recommend using +one of these pins to take your measurements. More details in the +:ref:`Maple hardware documentation <maple-adc-bank>`. + +Board-Specific Values +--------------------- + +This section lists the Maple RET6 Edition's :ref:`board-specific +values <lang-board-values>`. + +- ``CYCLES_PER_MICROSECOND``: 72 +- ``BOARD_BUTTON_PIN``: 38 +- ``BOARD_LED_PIN``: 13 +- ``BOARD_NR_GPIO_PINS``: 44 (however, :ref:`pin D43 is not usable + <maple-nrst-pb4>`) +- ``BOARD_NR_PWM_PINS``: 18 +- ``boardPWMPins``: 0, 1, 2, 3, 5, 6, 7, 8, 9, 11, 12, 14, 24, 27, 28, + 35, 36, 37 +- ``BOARD_NR_ADC_PINS``: 15 +- ``boardADCPins``: 0, 1, 2, 3, 10, 11, 12, 15, 16, 17, 18, 19, 20, 27, 28 +- ``BOARD_NR_USED_PINS``: 7 +- ``boardUsedPins``: ``BOARD_LED_PIN``, ``BOARD_BUTTON_PIN``, + ``BOARD_JTMS_SWDIO_PIN``, ``BOARD_JTCK_SWCLK_PIN``, + ``BOARD_JTDI_PIN``, ``BOARD_JTDO_PIN``, ``BOARD_NJTRST_PIN`` +- ``BOARD_NR_USARTS``: 3 (unfortunately, :ref:`due to the Maple Rev 5 + design <maple-ret6-uarts>`, UARTs 4 and 5 have pins which are not + broken out). +- ``BOARD_USART1_TX_PIN``: 7 +- ``BOARD_USART1_RX_PIN``: 8 +- ``BOARD_USART2_TX_PIN``: 1 +- ``BOARD_USART2_RX_PIN``: 0 +- ``BOARD_USART3_TX_PIN``: 29 +- ``BOARD_USART3_RX_PIN``: 30 +- ``BOARD_NR_SPI``: 2 (unfortunately, :ref:`due to the Maple Rev 5 + design <maple-ret6-nrst-pb4>`, SPI3 is unavailable). +- ``BOARD_SPI1_NSS_PIN``: 10 +- ``BOARD_SPI1_MOSI_PIN``: 11 +- ``BOARD_SPI1_MISO_PIN``: 12 +- ``BOARD_SPI1_SCK_PIN``: 13 +- ``BOARD_SPI2_NSS_PIN``: 31 +- ``BOARD_SPI2_MOSI_PIN``: 34 +- ``BOARD_SPI2_MISO_PIN``: 33 +- ``BOARD_SPI2_SCK_PIN``: 32 +- ``BOARD_JTMS_SWDIO_PIN``: 39 +- ``BOARD_JTCK_SWCLK_PIN``: 40 +- ``BOARD_JTDI_PIN``: 41 +- ``BOARD_JTDO_PIN``: 42 +- ``BOARD_NJTRST_PIN``: :ref:`43 <maple-ret6-nrst-pb4>` + +.. _maple-ret6-hardware: + +Hardware Design Files +--------------------- + +The hardware schematics and board layout files are available in the +`Maple GitHub repository <https://github.com/leaflabs/maple>`_. Other +than the processor used, the design files for the Maple RET6 edition +are identical to the Maple Rev 5, which are in the ``maple-r5`` +subdirectory of the Maple repository. A schematic for a JTAG adapter +suitable for use with Maple is available in the ``jtagadapter`` +directory. + +From the GitHub repository main page, you can download the entire +repository by clicking the "Download" button. If you are familiar +with `Git <http://git-scm.com/>`_, you can also clone the repository +at the command line with :: + + $ git clone git://github.com/leaflabs/maple.git + +.. _maple-ret6-failure-modes: + +Failure Modes +------------- + +The following known failure modes apply to all Maple boards. The +failure modes aren't design errors, but are easy ways to break or +damage your board permanently. + +* **High voltage on non-tolerant pins**: not all header pins are 5V + compatible; so e.g. connecting certain serial devices in the wrong + way could over-voltage the pins. The :ref:`pin-mapping master table + <maple-ret6-pin-map-master>` details which pins are + :ref:`5V-tolerant <gpio-5v-tolerant>`. + +Errata +------ + +This section lists known issues and warnings for the Maple RET6 +Edition. Some of these are simply due to the RET6 Edition using the +Maple's circuit board, which was not designed to accomodate extra +features only available on the STM32F103RET6. + +.. _maple-ret6-barrel-jack: + +* **Barrel jack power supply voltage mistake**: The acceptable voltage + range given next to the barrel jack on the Maple RET6 is + **incorrect**. The given range is 7V — 18V. In fact, **18V is too + high** and should not be supplied to your board. The original + voltage regulators used on the Maple were rated up to 18V. However, + the voltage regulators on current Maple Revs are rated up to only + 16V, and due to the current draw requirements of the board, operate + properly only up to 12V. The recommended maximum voltage you should + apply is **12V**, and potentially even lower depending upon the + current draw requirements of the application. Please see :ref:`Power + Regulation on the Maple <maple-power-regulation>` for more + information. + +* **Power supply marketing mistake**: We originally sold the Maple + RET6 Edition advertising that it was capable of supplying up to 800 + mA; the correct value is 500 mA. + +.. _maple-ret6-uarts: + +* **UART4, UART5 GPIOs unavailable**: Pins related to UARTs 4 and 5 + are not broken out to headers (specifically, PC11/UART4_RX and + PC12/UART5_TX). This is due to the RET6 Edition's board layout + being that of the Maple Rev 5, which was not designed with these + RET6-specific features in mind. + +.. _maple-ret6-dac-ch2: + +* **DAC channel 2 on BOARD_LED_PIN**: The Maple Rev 5 connects PA5 to + the board's built-in LED; this is the same GPIO bit which is + connected to the DAC's channel 2 output. This is also due to the + RET6 Edition's board layout being that of the Maple Rev 5. The DAC + output channel is still available, and (if you use the + :ref:`standard libmaple DAC interface <libmaple-dac>`) its output is + buffered by default, so this may not significantly interfere with + its functionality. + +.. _maple-ret6-nrst-pb4: + +* **Reset and PB4 tied together**: The RET6 Edition's reset line is + also connected to PB4, which is labeled on the silkscreen as pin 43. + Thus, attempting to use pin 43 as a GPIO can reset your board. This + has other implications. Since PB4 is also the JTAG NJTRST line, + this prevents the :ref:`JTAG <jtag>` "reset halt" command from + working properly. Also, since PB4 is SPI3_MISO, the SPI3 peripheral + is not fully usable. + +.. _maple-ret6-sdio: + +* **SDIO lines not broken out**: The RET6 Edition's SDIO peripheral is + not usable, as some of its data lines are either not broken out or + used for other purposes. This is also due to the RET6 Edition's + board layout being that of the Maple Rev 5. + +.. _maple-ret6-adc-led: + +* **ADC on BOARD_LED_PIN**: We originally sold the Maple RET6 Edition + advertising 16 analog input lines. However, one of them (the one on + pin 13) is also connected to the built-in LED. The voltage drop + across the LED means that the analog to digital converter on that + pin is not really useful. While it is still usable, its readings + will be incorrect. + +Recommended Reading +------------------- + +.. _maple-ret6-stdocs: + +STMicro documentation for STM32F103RE microcontroller: + +* `Datasheet + <http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/DATASHEET/CD00191185.pdf>`_ + (PDF); covers STM32F103xC, STM32F103xD, STM32F103xE. +* `Reference Manual RM0008 + <http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/REFERENCE_MANUAL/CD00171190.pdf>`_ + (PDF); definitive resource for peripherals on the STM32F1 line. +* `Programming Manual PM0056 + <http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/PROGRAMMING_MANUAL/CD00228163.pdf>`_ + (PDF); assembly language and register reference. +* `STM32F103RE <http://www.st.com/internet/mcu/product/164485.jsp>`_ + overview page with links to further references. diff --git a/docs/source/hardware/maple.rst b/docs/source/hardware/maple.rst new file mode 100644 index 0000000..b187115 --- /dev/null +++ b/docs/source/hardware/maple.rst @@ -0,0 +1,618 @@ +.. highlight:: sh + +.. _maple: + +Maple +===== + +This page is a general resource for information specific to the Maple. + +.. contents:: Contents + :local: + +.. TODO [dma.rst] Ref to dma.rst in sequel instead of libmaple-dma +.. TODO [nvic.rst] Ref to nvic.rst in sequel + +Technical Specifications +------------------------ + +* MCU: :ref:`STM32F103RBT6 <maple-stdocs>`, a 32-bit ARM Cortex M3 + microprocessor +* Clock Speed: **72 MHz** +* **128 KB Flash** and **20 KB SRAM** +* 43 :ref:`digital I/O pins (GPIOs) <gpio>` +* 15 :ref:`PWM <pwm>` pins at 16 bit resolution +* 15 :ref:`analog input (ADC) <adc>` pins at 12-bit resolution +* 2 :ref:`SPI <spi>` peripherals +* 2 :ref:`I2C <i2c>` peripherals +* 7 Channels of Direct Memory Access (**DMA**) (:ref:`libmaple-dma`) +* 3 :ref:`USART (serial port) <usart>` peripherals +* One advanced and three general-purpose :ref:`timers <timers>` +* Dedicated :ref:`USB <usb>` port for programming and communications +* :ref:`JTAG <jtag>` +* Nested Vectored Interrupt Controller (NVIC) (including + :ref:`external interrupt <external-interrupts>` on GPIOs) +* Supplies up to 500 mA at 3.3 V, with separate 250 mA digital and + analog regulators for low-noise analog performance +* :ref:`Open source, four layer design <maple-hardware>` +* Support for low power, sleep, and standby modes (<500 μA) +* Operating Voltage: 3.3 V +* Input Voltage (recommended): 4 V — 12 V +* Dimensions: 2.05″ × 2.1″ + +.. _maple-identify-rev: + +Identifying your Rev +-------------------- + +We went through three versions ("Revs") of the Maple hardware: Rev 1, +Rev 3, and Rev 5 [#frev2_4]_; Rev 5, the final design, is currently on +sale. The following sections will help you to help you identify your +Rev. + +Rev 5 +^^^^^ + +These boards went on sale in November 2010. They have white buttons +and "r5" in small print near the "LeafLabs Maple" text next to the +"infinity leaf" logo. The Maple Rev 5 repositioned the double header +on the right hand side to better fit 0.1 inch pitch breadboard. This +necessitated the removal of pins 21 and 22 from the double header; +they are still available, but don't have any headers installed on +them. + +.. figure:: /_static/img/maple_rev5.png + :align: center + :alt: Maple Rev 5 + +Rev 3 +^^^^^ + +This batch of boards went on sale beginning in May 2010. They have a +darker red silkscreen and the "infinity leaf" logo. The Maple Rev 3 +was the first version which includes the built-in button, labeled BUT. + +.. figure:: /_static/img/maple_rev3.png + :align: center + :alt: Maple Rev 3 + +Rev 1 +^^^^^ + +A small number of Maple Rev 1 boards went on sale in late 2009. They +have a light red silkscreen and a single pixelated leaf as a logo. + +.. figure:: /_static/img/maple_rev1.png + :align: center + :alt: Maple Rev 1 + +.. _maple-powering: + +Powering the Maple +------------------ + +The Maple's power source is determined by the header to the left of +the "LeafLabs" label on the silkscreen. All versions of the Maple can +be powered from the barrel jack connector, USB, or a LiPo battery. We +ship the Maple with a jumper on the USB selector. In order to power +it off of an alternative source, unplug the Maple, then move the +jumper to the desired selector before reconnecting power. + +You can also power the Maple via the pin labeled "Vin" on the lower +header. This pin feeds into both the digital and analog voltage +regulators. However, don't do this while simultaneously powering the +board from another source, or you could damage it. + +When powering the board from a barrel jack, **double check the +polarity of the barrel.** The appropriate polarity is noted on the +silkscreen right next to the connector. + +.. warning:: Silkscreens on Maples up through Rev 5s manufactured in + Spring 2011 falsely indicated that the barrel jack could be + supplied by up to 18V. (Rev5s manufactured after Spring 2011 may + still have this error on the silk, but it has been marked over.) We + recommend a barrel jack input voltage **no greater than 12V**, and + potentially even lower depending upon the current draw requirements + of the application. The same goes for powering off LiPo batteries. + + Please see :ref:`Power Regulation on the Maple + <maple-power-regulation>` for more information. + +.. _maple-power-regulation: + +Power Regulation on the Maple +----------------------------- + +Power regulation on the Maple is provided by two low dropout linear +voltage regulators. (The part is the MCP1703 from Microchip, in the +SOT-23A package. You can download the datasheet `here +<http://ww1.microchip.com/downloads/en/DeviceDoc/22049a.pdf>`_ ). One +of the regulators supplies power to the digital voltage plane; the +other supplies power to the analog voltage plane. + +These voltage regulators nominally take an input of up to 16V. In +addition, while the maximum continuous output current for the board is +250mA, if you are powering the board off higher voltages the current +it can supply goes down, due to the regulators needing to dissipate +the extra power. So if you are powering the board off 12V, the max +current is about 40mA at room temperature. In general (again, at room +temperature) the max power dissipation (PD) for the chip is about +.37W, and output current = PD/(Vin-Vout). For exact max current +calculations, please refer to the datasheet linked above. + +If you are planning to draw a lot of current from the Maple board, it +is necessary to provide input power as close to 3.3V as +possible. Powering the microcontroller circuitry and LEDs on the board +alone takes approximately 30mA, so if you are powering the board with +12V that leaves only 10mA (at best) available for powering any user +circuitry. Attempting to draw more than 10mA runs the risk of shorting +out the power regulators and bricking your board. + +Using the Built-in Battery Charger +---------------------------------- + +Maples Rev 3 and Rev 5 also have a built-in LiPo battery charger. In +order to use it, put a jumper across the CHRG header on the power +selection header and across the USB, or EXT selectors, depending on +whether you're charging the battery via USB cable or barrel jack +connector. The LED labeled CHRG will light up while the battery is +being charged. When the battery is finished charging, the LED labeled +DONE will light up. + +.. _maple-gpios: + +GPIO Information +---------------- + +The Maple features 38 ready-to-use general purpose input/output (see +:ref:`gpio`) pins for digital input/output, numbered ``D0`` through +``D37``. These numbers correspond to the numeric values next to each +header on the Maple silkscreen. + +.. _maple-ret6-but: + +Pin ``D38`` is the board's :ref:`button pin <lang-board-values-but>`. +It is thus mainly useful as an :ref:`input <lang-pin-levels>`. The +pin will :ref:`read <lang-digitalread>` ``HIGH`` when the :ref:`button +is pressed <lang-isbuttonpressed>`. + +More GPIOs (numbered ``D39``\ --``D42`` on the back of the Maple's +silkscreen) are available if you use the :ref:`lang-disabledebugports` +function; see the :ref:`board-specific debug pin constants +<lang-board-values-debug>` for more information. (See :ref:`this +erratum <maple-nrst-pb4>` for information about the pin numbered +``43`` on the silkscreen). + +.. TODO [0.1.0] silkscreen pictures which expand abbreviations + +.. _maple-pin-map-master: + +Master Pin Map +^^^^^^^^^^^^^^ + +This table shows a summary of the available functionality on every +GPIO pin, by peripheral type. The "5 V?" column documents whether or +not the pin is :ref:`5 volt tolerant <gpio-5v-tolerant>`. + +Note that this table is not exhaustive; on some pins, more peripherals +are available than are listed here. + +.. csv-table:: + :header: Pin, :ref:`GPIO <gpio>`, :ref:`ADC <adc>`, :ref:`Timer <timers>`, :ref:`I2C <i2c>`, :ref:`UART <usart>`, :ref:`SPI <spi>`, 5 V? + + D0, PA3, CH3, 2_CH4, -, 2_RX, -, - + D1, PA2, CH2, 2_CH3, -, 2_TX, -, - + D2, PA0, CH0, 2_CH1_ETR, -, 2_CTS, -, - + D3, PA1, CH1, 2_CH2, -, 2_RTS, -, - + D4, PB5, -, -, 1_SMBA, -, -, - + D5, PB6, -, 4_CH1, 1_SCL, -, -, Yes + D6, PA8, -, 1_CH1, -, 1_CK, -, Yes + D7, PA9, -, 1_CH2, -, 1_TX, -, Yes + D8, PA10, -, 1_CH3, -, 1_RX, -, Yes + D9, PB7, -, 4_CH2, 1_SDA, -, -, Yes + D10, PA4, CH4, -, -, 2_CK, 1_NSS, - + D11, PA7, CH7, 3_CH2, -, -, 1_MOSI, - + D12, PA6, CH6, 3_CH1, -, -, 1_MISO, - + D13, PA5, CH5, -, -, -, 1_SCK, - + D14, PB8, -, 4_CH3, -, -, -, Yes + D15, PC0, CH10, -, -, -, -, - + D16, PC1, CH11, -, -, -, -, - + D17, PC2, CH12, -, -, -, -, - + D18, PC3, CH13, -, -, -, -, - + D19, PC4, CH14, -, -, -, -, - + D20, PC5, CH15, -, -, -, -, - + D21, PC13, -, -, -, -, -, - + D22, PC14, -, -, -, -, -, - + D23, PC15, -, -, -, -, -, - + D24, PB9, -, 4_CH4, -, -, -, Yes + D25, PD2, -, 3_ETR, -, -, -, Yes + D26, PC10, -, -, -, -, -, Yes + D27, PB0, CH8, 3_CH3, -, -, -, - + D28, PB1, CH9, 3_CH4, -, -, -, - + D29, PB10, -, -, 2_SCL, 3_TX, -, Yes + D30, PB11, -, -, 2_SDA, 3_RX, -, Yes + D31, PB12, -, -, 2_SMBA, 3_CK, 2_NSS, Yes + D32, PB13, -, -, -, 3_CTS, 2_SCK, Yes + D33, PB14, -, -, -, 3_RTS, 2_MISO, Yes + D34, PB15, -, -, -, -, 2_MOSI, Yes + D35, PC6, -, -, -, -, -, Yes + D36, PC7, -, -, -, -, -, Yes + D37, PC8, -, -, -, -, -, Yes + D38, PC9, -, -, -, -, -, Yes + D39, PA13, -, -, -, -, -, Yes + D40, PA14, -, -, -, -, -, Yes + D41, PA15, -, -, -, -, -, Yes + D42, PB3, -, -, -, -, -, Yes + +.. _maple-gpio-port-map: + +GPIO Port Pin Map +^^^^^^^^^^^^^^^^^ + +The following table shows what pins are associated with each +:ref:`GPIO port <gpio-ports>`. + +.. csv-table:: + :header: GPIOA, GPIOB, GPIOC + + PA0: D2, PB0: D27, PC0: D15 + PA1: D3, PB1: D28, PC1: D16 + PA2: D1, PB2: -, PC2: D17 + PA3: D0, PB3: D42, PC3: D18 + PA4: D10, PB4: D43, PC4: D19 + PA5: D13, PB5: D4, PC5: D20 + PA6: D12, PB6: D5, PC6: D35 + PA7: D11, PB7: D9, PC7: D36 + PA8: D6, PB8: D14, PC8: D37 + PA9: D7, PB9: D24, PC9: D38 + PA10: D8, PB10: D29, PC10: D26 + PA11: -, PB11: D30, PC11: - + PA12: -, PB12: D31, PC12: - + PA13: D39, PB13: D32, PC13: D21 + PA14: D40, PB14: D33, PC14: D22 + PA15: D41, PB15: D34, PC15: D23 + +.. _maple-timer-map: + +Timer Pin Map +^^^^^^^^^^^^^ + +The following table shows what pins are associated with a particular +timer's capture/compare channels. + +.. csv-table:: + :header: Timer, Ch. 1, Ch. 2, Ch. 3, Ch. 4 + :delim: | + + 1 | D6 | D7 | D8 | - + 2 | D2 | D3 | D1 | D0 + 3 | D12 | D11 | D27 | D28 + 4 | D5 | D9 | D14 | D24 + +.. _maple-exti-map: + +EXTI Line Pin Map +^^^^^^^^^^^^^^^^^ + +The following table shows which pins connect to which :ref:`EXTI lines +<external-interrupts-exti-line>` on the Maple. + +.. list-table:: + :widths: 1 1 + :header-rows: 1 + + * - EXTI Line + - Pins + * - EXTI0 + - D2, D15, D27 + * - EXTI1 + - D3, D16, D28 + * - EXTI2 + - D1, D17, D25 + * - EXTI3 + - D0, D18, D42 + * - EXTI4 + - D10, D19 + * - EXTI5 + - D4, D13, D20 + * - EXTI6 + - D5, D12, D35 + * - EXTI7 + - D9, D11, D36 + * - EXTI8 + - D6, D14, D37 + * - EXTI9 + - D7, D24, D38 + * - EXTI10 + - D8, D26, D29 + * - EXTI11 + - D30 + * - EXTI12 + - D31 + * - EXTI13 + - D21, D32, D39 + * - EXTI14 + - D22, D33, D40 + * - EXTI15 + - D23, D34, D41 + +.. _maple-usart-map: + +USART Pin Map +^^^^^^^^^^^^^ + +The Maple has three serial ports (also known as :ref:`USARTs +<usart>`): ``Serial1``, ``Serial2``, and ``Serial3``. They communicate +using the pins given in the following table. + +.. csv-table:: + :header: Serial Port, TX, RX, CK, CTS, RTS + :delim: | + + ``Serial1`` | D7 | D8 | D6 | | + ``Serial2`` | D1 | D0 | D10 | D2 | D3 + ``Serial3`` | D29 | D30 | D31 | D32 | D33 + +.. _maple-adc-bank: + +Low-Noise ADC Pins +^^^^^^^^^^^^^^^^^^ + +The six pins at the bottom right of the board (D15—D20) generally +offer lower-noise ADC performance than other pins on the board. If +you’re concerned about getting good ADC readings, we recommend using +one of these pins to take your measurements. + +Maple has an electrically isolated analog power plane with its own +regulator, and a geometrically isolated ground plane. Pins D15—D20 are +laid out to correspond with these analog planes, and our measurements +indicate that they generally have the lowest noise of all the analog +lines. However, analog performance may vary depending upon the +activity of the other GPIOs. Consult the :ref:`Maple hardware design +files <maple-hardware>` for more details. + +Board-Specific Values +--------------------- + +This section lists the Maple's :ref:`board-specific values +<lang-board-values>`. + +- ``CYCLES_PER_MICROSECOND``: 72 +- ``BOARD_BUTTON_PIN``: 38 +- ``BOARD_LED_PIN``: 13 +- ``BOARD_NR_GPIO_PINS``: 44 (however, :ref:`pin D43 is not usable + <maple-nrst-pb4>`) +- ``BOARD_NR_PWM_PINS``: 15 +- ``boardPWMPins``: 0, 1, 2, 3, 5, 6, 7, 8, 9, 11, 12, 14, 24, 27, 28 +- ``BOARD_NR_ADC_PINS``: 15 +- ``boardADCPins``: 0, 1, 2, 3, 10, 11, 12, 15, 16, 17, 18, 19, 20, 27, 28 +- ``BOARD_NR_USED_PINS``: 7 +- ``boardUsedPins``: ``BOARD_LED_PIN``, ``BOARD_BUTTON_PIN``, + ``BOARD_JTMS_SWDIO_PIN``, ``BOARD_JTCK_SWCLK_PIN``, + ``BOARD_JTDI_PIN``, ``BOARD_JTDO_PIN``, ``BOARD_NJTRST_PIN`` +- ``BOARD_NR_USARTS``: 3 +- ``BOARD_USART1_TX_PIN``: 7 +- ``BOARD_USART1_RX_PIN``: 8 +- ``BOARD_USART2_TX_PIN``: 1 +- ``BOARD_USART2_RX_PIN``: 0 +- ``BOARD_USART3_TX_PIN``: 29 +- ``BOARD_USART3_RX_PIN``: 30 +- ``BOARD_NR_SPI``: 2 +- ``BOARD_SPI1_NSS_PIN``: 10 +- ``BOARD_SPI1_MOSI_PIN``: 11 +- ``BOARD_SPI1_MISO_PIN``: 12 +- ``BOARD_SPI1_SCK_PIN``: 13 +- ``BOARD_SPI2_NSS_PIN``: 31 +- ``BOARD_SPI2_MOSI_PIN``: 34 +- ``BOARD_SPI2_MISO_PIN``: 33 +- ``BOARD_SPI2_SCK_PIN``: 32 +- ``BOARD_JTMS_SWDIO_PIN``: 39 +- ``BOARD_JTCK_SWCLK_PIN``: 40 +- ``BOARD_JTDI_PIN``: 41 +- ``BOARD_JTDO_PIN``: 42 +- ``BOARD_NJTRST_PIN``: :ref:`43 <maple-nrst-pb4>` + +.. _maple-hardware: + +Hardware Design Files +--------------------- + +The hardware schematics and board layout files are available in the +`Maple GitHub repository <https://github.com/leaflabs/maple>`_. The +design files for Rev 1, Rev 3, and Rev 5 are respectively in the +``maple-r1``, ``maple-r3``, and ``maple-r5`` subdirectories. A +schematic for a JTAG adapter suitable for use with Maple is available +in the ``jtagadapter`` directory. + +From the GitHub repository main page, you can download the entire +repository by clicking the "Download" button. If you are familiar +with `Git <http://git-scm.com/>`_, you can also clone the repository +at the command line with :: + + $ git clone git://github.com/leaflabs/maple.git + +.. _maple-failure-modes: + +Failure Modes +------------- + +The following are known failure modes. The failure modes aren't +design errors, but are easy ways to break or damage your board +permanently. + +* **High voltage on non-tolerant pins**: not all header pins are 5V + compatible; so e.g. connecting certain serial devices in the wrong + way could over-voltage the pins. The :ref:`pin-mapping master table + <maple-pin-map-master>` details which pins are :ref:`5 V tolerant + <gpio-5v-tolerant>`. + +Errata +------ + +This section documents design flaws and other errors. + +General +^^^^^^^ + +.. _maple-barrel-jack: + +* **Barrel jack power supply voltage mistake**: The acceptable voltage + range given next to the barrel jack on the Maple through Rev 5s + manufactured in Spring 2011 is **incorrect**. The given range is 7V + — 18V. In fact, **18V is too high** and should not be supplied to + your board. The original voltage regulators used on the Maple were + rated up to 18V. However, the voltage regulators on current Maple + Revs are rated up to only 16V, and due to the current draw + requirements of the board, operate properly only up to 12V. The + recommended maximum voltage you should apply is **12V**, and + potentially even lower depending upon the current draw requirements + of the application. Please see :ref:`Power Regulation on the Maple + <maple-power-regulation>` for more information. + +.. _maple-nrst-pb4: + +* **Reset and PB4 tied together**: The Maple's reset line is also + connected to PB4, which is labeled on the silkscreen as pin 43. + Thus, attempting to use pin 43 as a GPIO can reset your board. This + has other implications. Since PB4 is also the JTAG NJTRST line, + this prevents the :ref:`JTAG <jtag>` "reset halt" command from + working properly. + +.. _maple-power-supply: + +* **Power supply marketing mistake**: We originally sold the Maple + advertising that it was capable of supplying up to 800 mA; the + correct value is 500 mA. + +.. _maple-pwm-marketing: + +* **PWM marketing mistake**: We originally advertised the Maple as + having 22 PWM-capable pins; the correct number is 15. + +.. _maple-adc-marketing: + +* **ADC marketing mistake**: We originally advertised the Maple as + having 16 analog input pins. Due to :ref:`the following issue + <maple-adc-led>`, the correct number is 15. + +.. _maple-adc-led: + +* **ADC on BOARD_LED_PIN**: We originally sold the Maple RET6 Edition + advertising 16 analog input lines. However, one of them (the one on + pin 13) is also connected to the built-in LED. The voltage drop + across the LED means that the analog to digital converter on that + pin is not really useful. While it is still usable, its readings + will be incorrect. + + +By Rev +^^^^^^ + +The following subsections lists known issues and warnings for each +revision of the Maple board. + +Rev 5 +~~~~~ + +* **Pin 3 AIN missing**: Pin 3 is capable of analog input, but on Rev + 5s manufactured during Fall 2010, the corresponding "AIN" is missing + from its silkscreen. This mistake was fixed in later manufacturing + runs. + +Rev 3 +~~~~~ + +* **Pin 3 AIN missing**: Pin 3 is capable of analog input, but the + corresponding "AIN" is missing from the Rev 3 silkscreen. + +.. _maple-rev3-bad-buttons: + +* **Bad/Sticky Buttons**: a number of Rev 3 boards sold in May-June 2010 + have questionable RESET and BUT buttons. + + What seems to have happened is that the flux remover we used to + clean the boards before shipping eroded the plastic internals, which + resulted in intermittent functionality. All buttons on all shipped + boards did function in testing, but some may have been unreliable in + regular use. + + If you have this problem, we will be happy to ship you new buttons + if you think you can re-solder them yourself, or you can ship us + your board and we will swap out that part. + + For reference, the button part number is KMR211GLFS and the flux + remover we used is "Precision Electronics Cleaner" from RadioShack, + which is "Safe on most plastics" and contains: dipropylene glycol + monomethyl ether, hydrotreated heavy naphtha, dipropylene glycol + methyl ether acetate (say that three times fast!), and carbon + dioxide. + +* **Resistors on pins 0 and 1**: these header pins, which are RX/TX on + USART2 (:ref:`Serial2 <lang-serial>`), have resistors in-line + between the STM32 and the headers. These resistors increase the + impedance of the lines for ADC reads and affect the open drain GPIO + functionality of the pins. + + These resistors were accidentally copied over from older Arduino USB + designs, where they appear to protect the USB-Serial converter from + TTL voltage on the headers. + +* **Silkscreen Errors**: the silkscreen on the bottom indicated PWM + functionality on pin 25 and listen the external header GND pin as + number 38 (actually 38 is connected to the BUT button). We manually + sharpied over both of these mistakes. + +Rev 1 +~~~~~ + +* **ADC noise**: generally very high, in particular when the USB port + is being used for communications (including keep-alive pings when + connected to a computer). + + This issue was resolved in Rev 3 with a 4-layer design and a + :ref:`geometrically isolated ADC Vref plane <maple-adc-bank>`. + +* **Resistors on pins 0 and 1**: these header pins, which are RX/TX on + USART2 (:ref:`Serial2 <lang-serial>`), have resistors in-line + between the STM32 and the headers. These resistors increase the + impedance of the lines for ADC reads and affect the open drain GPIO + functionality of the pins. + + These resistors were accidentally copied over from older Arduino USB + designs, where they appear to protect the USB-Serial converter from + TTL voltage on the headers. + +* **Silkscreen Differences**: the pin numbering scheme on Rev 1 is + different from Rev 3, and thus Rev 3 software is difficult to use + with Rev 1 boards. Notably, the analog input bank is labeled A0-A4 + on Rev 1 but 15-20 on Rev 3, and the extra header bank does not have + a pinout table on the bottom. + +* **No BUT Button**: the BUT button, useful for serial bootloading, + was only added in Rev 3. As a workaround, you can directly short the + appropriate MCU pin to Vcc; see `this forum posting + <http://forums.leaflabs.com/topic.php?id=32#post-126>`_. + +Recommended Reading +------------------- + +.. _maple-stdocs: + +STMicro documentation for STM32F103RB microcontroller: + +* `Datasheet + <http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/DATASHEET/CD00161566.pdf>`_ + (PDF); covers STM32F103x8, STM32F103xB. +* `Reference Manual RM0008 + <http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/REFERENCE_MANUAL/CD00171190.pdf>`_ + (PDF); definitive resource for peripherals on the STM32F1 line. +* `Programming Manual PM0056 + <http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/PROGRAMMING_MANUAL/CD00228163.pdf>`_ + (PDF); assembly language and register reference. +* `STM32F103RB <http://www.st.com/internet/mcu/product/164487.jsp>`_ + overview page with links to further references. + +.. rubric:: Footnotes + +.. [#frev2_4] Revs 2 and 4 were prototypes that didn't pass internal + testing. diff --git a/docs/source/i2c.rst b/docs/source/i2c.rst new file mode 100644 index 0000000..a206ed4 --- /dev/null +++ b/docs/source/i2c.rst @@ -0,0 +1,77 @@ +.. _i2c: + +|i2c| +===== + +|i2c| is a crude and easy-to-hack serial protocol that requires only +two wires/channels for communication between Maple and many other +devices. + +.. contents:: Contents + :local: + +Overview +-------- + +Communication via |i2c| is broken up into messages. Every message is +between a *master* device, which initiates the message, and a *slave* +device, which responds. + +Slaves are addressed using 7-bit addresses (up to 127 unique devices); +10-bit addressing is also possible. Every message consists of an +arbitrary combination of 8-bit reads and writes as requested by the +master. Higher level functionality, such as reading a particular +register value, is achieved by writing to set the memory location then +reading to pull out the data. + +Note that the master/slave designation is on a message-by-message +basis. Maple can act as both a master (messages initiated by user +code) and slave device (responding to requests via configurable +interrupt handlers) at the same time (though slave mode is currently +unimplemented). + +Hardware/Circuit Design +----------------------- + +.. FIXME [0.1.0] Link to board-specific values (BOARD_I2C1_SDA_PIN, etc.) + +Maple boards have two |i2c| ports. Maples reliably communicate with +up to a 400kHz clock speed; this doesn't translate into a 400kbps +data rate except in extreme cases because of addressing and protocol +overhead. We have tested clock speeds up to a megahertz and have had +mixed results; in theory, it could be possible to achieve even higher +rates, but signal quality degrades rapidly, and the bus becomes +unreliable. + +Proper wiring and pull-up resistor selection are essential when +incorporating |i2c| into a circuit, especially with data rates above +100kHz. In the lab, we usually use approximately 5kΩ resistors with +|vcc| (3.3V) as the high voltage, and try to connect the pullup +voltage as close to the SDA and SCL pins as possible. We recommend +looking at the ST reference website for |i2c| (see the +:ref:`recommended reading <i2c-recommended-reading>` below), starting +with a slow clock rate (10kHz), and, if possible, using an +oscilloscope to debug any issues. + +Function Reference +------------------ + +Currently, only low-level support in :ref:`libmaple-i2c` exists. A +Wiring-style library is planned for a future release. + +SMBus +----- + +The STM32 microcontroller has hardware support for SMBus, but software +for it is not yet implemented. + +.. _i2c-recommended-reading: + +Recommended Reading +------------------- + +* `I2C Bus <http://www.i2c-bus.org/>`_ +* `Wikipedia: I2C <http://en.wikipedia.org/wiki/I%C2%B2C>`_ +* `Arduino I2C/TWI reference <http://www.arduino.cc/en/Reference/Wire>`_ +* ST `Application note STM32F10xxx I2C optimized examples + <http://www.st.com/st-web-ui/static/active/en/resource/technical/document/application_note/CD00209826.pdf>`_ (PDF) diff --git a/docs/source/ide.rst b/docs/source/ide.rst new file mode 100644 index 0000000..e6d49fc --- /dev/null +++ b/docs/source/ide.rst @@ -0,0 +1,166 @@ +.. _ide: + +Using Maple IDE +=============== + +This page documents the basic functionality of the Maple IDE. +Specifically, it describes the operation of the buttons on the main +toolbar. It is expected to become more comprehensive over time. + +If you're new to Maple, you should begin with the :ref:`Maple +Quickstart <maple-quickstart>`. + +If you need to install the IDE for the first time, see the +:ref:`maple-ide-install` page. + +.. contents:: Contents + :local: + +IDE Windows +----------- + +The following screenshot shows the appearance of a Maple IDE window: + +.. figure:: /_static/img/ide-blinky.png + :align: center + :alt: Maple IDE + +Note the toolbar buttons at the top; they're the icons with circles or +squares around them. You can program your board mostly through the +use of these buttons, which are described in the next section. + +Toolbar Buttons +--------------- + +.. _ide-verify: + +Verify +~~~~~~ + +.. image:: /_static/img/button-verify.png + :align: left + +Click Verify to compile the current sketch. This will process your +program and produce an executable which can run on your board. + +.. _ide-stop: + +Stop +~~~~ + +.. image:: /_static/img/button-stop.png + :align: left + +Click Stop to cancel a compilation. Longer programs may take a while +to compile. Clicking Stop will let you go back to writing code +without having to wait for compilation to finish. + +.. _ide-new: + +New +~~~ + +.. image:: /_static/img/button-new.png + :align: left + +Click New to make a fresh sketch. + +.. _ide-open: + +Open +~~~~ + +.. image:: /_static/img/button-open.png + :align: left + +Click Open to open an existing sketch. Maple IDE will first look for +the sketch in your *sketchbook*, which is a folder on your computer +that contains your sketches. The sketchbook is stored in different +places depending on your operating system. You can change its +location in the IDE's preferences. + +.. _ide-save: + +Save +~~~~ + +.. image:: /_static/img/button-save.png + :align: left + +Click Save to save the currently opened sketch. This will save all +open tabs, not just the one you're currently looking at. + +.. _ide-upload: + +Upload +~~~~~~ + +.. image:: /_static/img/button-upload.png + :align: left + +Click Upload to send the compiled sketch to your Maple to run. Before +you click Upload, you must have a memory location and serial port +selected. + +The memory location, either Flash or RAM, determines whether the +compiled sketch binary will be stored on the Maple. You can choose +this using the Tools > Board menu. + +The serial port corresponds to the :ref:`SerialUSB <lang-serialusb>` +connection the Maple establishes with your computer. This looks like +"COM1", "COM2", etc. on Windows, "/dev/tty.usbmodemXXX" on Mac (where +"XXX" is some sequence of letters and numbers), or "/dev/ttyACMXXX" on +Linux (again, where "XXX" is some sequence of letters and numbers). +You can choose a serial port using the Tools > Serial Port menu. + +If you're trying to upload and are unsuccessful, make sure you've made +choices for both board and serial port. More help on uploading +(including screenshots) is available in the :ref:`quickstart +<maple-quickstart-upload>`. + +If all else fails, try putting your Maple in :ref:`perpetual +bootloader mode <troubleshooting-perpetual-bootloader>` before +uploading. You can always find us on the `forum`_ or `contact us +directly`_ for help on any problems you're having. + +.. _ide-serial-monitor: + +Serial Monitor +~~~~~~~~~~~~~~ + +.. image:: /_static/img/button-serial-monitor.png + :align: left + +Click Serial Monitor to open up a communication channel between your +PC and the Maple's :ref:`SerialUSB <lang-serialusb>` virtual serial +port. + +If the serial monitor is open, any information sent to the computer +(for example, using :ref:`SerialUSB.println() +<lang-serialusb-println>`) will be displayed in the large text area. +You can send data to the Maple by typing into the small text box and +either hitting the Enter key or pressing the Send button. (The Maple +can read the data you send with :ref:`SerialUSB.read() +<lang-serialusb-read>`). + +Here is an example serial monitor session with the InteractiveTest +sketch (which you can load in the IDE by choosing menu item File > +Examples > Maple > InteractiveTest): + +.. image:: /_static/img/serial-monitor.png + +This is the result of typing "?" in the text box and clicking Send. + +.. note:: You cannot upload a sketch while the serial monitor is open. + If you click :ref:`Upload <ide-upload>` while the serial monitor is + open, the IDE will close it for you before proceeding with the + upload. + +.. _ide-examples: + +Example Code +------------ + +Maple IDE comes with a variety of sample code you can use to help you +get started writing your own programs. To load an example in a new +Maple IDE window, choose one from the submenus under File > Examples. diff --git a/docs/source/jtag.rst b/docs/source/jtag.rst new file mode 100644 index 0000000..caba223 --- /dev/null +++ b/docs/source/jtag.rst @@ -0,0 +1,81 @@ +.. highlight:: cpp + +.. _jtag: + +JTAG +==== + +.. FIXME [0.1.0] Updated adapter schematic, better information + +JTAG is an interface for low-level debugging of digital devices. It +gives instruction by instruction control over the microprocessor and +allows data to be read and written to arbitrary memory and register +locations. It is typically used with a debugging tool like `gdb +<http://www.gnu.org/software/gdb/>`_ when hacking low level routines +and hardware peripherals (we use it when working on :ref:`libmaple +<libmaple>`) or to flash a new bootloader. + +Note that the STM32 on the Maple has a built-in low level serial +debugger which could also be used to flash bootloaders, and +:ref:`lang-assert` allows basic debugging over a USART serial channel. +We expect only fairly advanced users to use this feature. + +.. contents:: Contents + :local: + +Wiring Diagram +-------------- + +.. figure:: /_static/img/jtag-wiring.png + :align: center + :alt: JTAG wiring diagram + :width: 7.4in + :target: _images/jtag-wiring.png + + JTAG wiring diagram (`large version <_images/jtag-wiring.png>`_) + to connect a standard 20-pin ARM JTAG device to the 8-pin JTAG port + on the Maple. + +The Maple has holes for a 8-pin JTAG header, but that header is not +soldered on. To use JTAG, simply solder on standard 0.1" pitch male +header pins (either the exact 4 by 2 block, or two 4-pin pieces of +straight breakaway header). + +Compatible Devices +------------------ + +We have had good experience with the `Olimex ARM-USB-OCD +<http://www.olimex.com/dev/arm-usb-ocd.html>`_ device, which costs +about €55 plus shipping (as of April 2011). + +Function Reference +------------------ + +You can disable or enable the JTAG and Serial Wire debugging ports in +software using the ``disableDebugPorts()`` and ``enableDebugPorts()`` +functions. + +* :ref:`lang-disabledebugports` +* :ref:`lang-enabledebugports` + +Recommended Reading +------------------- + +* `Wikipedia Article on Joint Test Action Group (JTAG) + <http://en.wikipedia.org/wiki/Joint_Test_Action_Group>`_ + +* `STM32, GDB, OpenOCD How To + <http://fun-tech.se/stm32/OpenOCD/gdb.php>`_ + +* `LeafLabs Wiki JTAG How To + <http://wiki.leaflabs.com/index.php?title=Maple_JTAG_How_To>`_ + +* `LeafLabs forum thread on JTAG + <http://forums.leaflabs.com/topic.php?id=536>`_ + +* ST documentation: + + * Reference Manual `RM0008 + <http://www.st.com/stonline/products/literature/rm/13902.pdf>`_ + (PDF), Chapter 31, "Debug support", and Chapter 9, + "General-purpose and alternate function I/Os". diff --git a/docs/source/lang/api/abs.rst b/docs/source/lang/api/abs.rst new file mode 100644 index 0000000..d9f1ca3 --- /dev/null +++ b/docs/source/lang/api/abs.rst @@ -0,0 +1,48 @@ +.. highlight:: cpp + +.. _lang-abs: + + +abs() +====== + +(Macro) computes the absolute value of a number. + +Syntax +------ + +:: + + abs(x) + +Parameters +---------- + +**x**: the number. + +Returns +------- + +**x**: if **x** is greater than or equal to 0. + +**-x**: if **x** is less than 0. + +Warning +------- + +Because of the way ``abs()`` is implemented, avoid using other +functions or causing side effects inside the parentheses, as it may +lead to incorrect results:: + + abs(a++); // avoid this - yields incorrect results + + abs(a); // use this instead - + a++; // keep other operations outside abs() + + +Arduino Compatibility +--------------------- + +Maple's implementation of ``abs()`` is compatible with Arduino. + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/api/analogread.rst b/docs/source/lang/api/analogread.rst new file mode 100644 index 0000000..6665a94 --- /dev/null +++ b/docs/source/lang/api/analogread.rst @@ -0,0 +1,119 @@ +.. highlight:: cpp + +.. _lang-analogread: + +.. _lang-api-analogread: + +analogRead() +============ + +Used to perform ADC conversion. + +.. contents:: Contents + :local: + +Library Documentation +--------------------- + +.. doxygenfunction:: analogRead + +Discussion +---------- + +Reads the value from the specified analog pin. The Maple boards +contain 16-channel, 12-bit analog to digital converters. This means +that a converter will map input voltages between 0 and 3.3 volts into +integer values between 0 and 4095. However, a number of factors +interfere with getting full accuracy and precision. For more +information, see :ref:`adc`. + +Before calling analogRead() on a pin, that pin must first be +configured for analog input, using :ref:`lang-pinMode`. You only have +to do this once, so it's usually done in :ref:`lang-setup`\ . + +Parameter Discussion +-------------------- + +The pin parameter is the number of the analog input pin to read from. +The pins which support analog to digital conversion have ``AIN`` +listed underneath their number on your board's silkscreen. These pin +numbers are available to your program in the :ref:`boardADCPins +<lang-board-values-adc-pins>` board-specific array. The number of +pins which are capable of analog to digital conversion on your board +is given by the ``BOARD_NR_ADC_PINS`` constant. These values are +documented for each board in the :ref:`Board Hardware Documentation +<index-boards>` pages. + +.. note:: Pin 3 is not marked ``AIN`` on the silkscreen for Maple + revisions through Rev 5; however **it does work** as an analog + input pin. + +Note +---- + +If the analog input pin is not connected to anything, the value +returned by ``analogRead()`` will fluctuate due to a number of reasons +(like the values of the other analog inputs, how close your hand is to +the board, etc.) in a "random" way. + +Example +------- + +:: + + int analogPin = 3; // Potentiometer wiper (middle terminal) connected + // to analog pin 3. outside leads to ground and +3.3V. + // You may have to change this value if your board + // cannot perform ADC conversion on pin 3. + + int val = 0; // variable to store the value read + + void setup() { + pinMode(analogPin, INPUT_ANALOG); // set up pin for analog input + } + + void loop() { + val = analogRead(analogPin); // read the input pin + SerialUSB.println(val); // print the value, for debugging with + // a serial monitor + } + +Arduino Compatibility +--------------------- + +The Arduino board contains a 6 channel (8 channels on the Mini and +Nano, 16 on the Mega), 10-bit analog to digital converter with an +input voltage range of 0V--5V. This means that it will map input +voltages between 0 and 5 volts (which is **larger** than Maple's range +of 0V-3.3V) into integer values between 0 and 1023 (which is +**smaller** than the Maple's range of 0--4095). + +This yields a theoretical resolution between readings of: 5 volts / +1024 units or .0049 volts (4.9 mV) per unit on Arduino boards, which +is larger, and thus less precise, than Maple's 0.0008 volts (0.8 mV). + +If your program expects Arduino-style 10-bit ADC, you can :ref:`right +shift <lang-bitshift>` the value of a Maple readout by 2, like so:: + + // right shift means that the result will be between 0 and 1023; + // be aware that you're losing a lot of precision if you do this + int adc_reading = analogRead(pin) >> 2; + +.. FIXME [0.1.0] Mention that Native can do analogReference() + +On the Arduino, the input range and resolution can be changed using +the `analogReference() +<http://arduino.cc/en/Reference/AnalogReference>`_ function. Because +of hardware restrictions, this function is not available on the Maple +and Maple RET6 Edition. If your inputs lie in a different voltage +range than 0V--3.3V, you'll need to bring them into that range before +using ``analogRead()``. See the :ref:`ADC reference <adc-range>` for +more information. + +See Also +-------- + +- :ref:`ADC tutorial <adc>` +- `(Arduino) Tutorial: Analog Input Pins <http://arduino.cc/en/Tutorial/AnalogInputPins>`_ + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/api/analogwrite.rst b/docs/source/lang/api/analogwrite.rst new file mode 100644 index 0000000..0169976 --- /dev/null +++ b/docs/source/lang/api/analogwrite.rst @@ -0,0 +1,181 @@ +.. highlight:: cpp + +.. _lang-analogwrite: + +.. _lang-api-analogwrite: + + +analogWrite() +============= + +analogWrite() is used to create a :ref:`PWM <pwm>` wave on a pin. + +.. note:: + + On the Maple, calling analogWrite() is the same as calling + :ref:`lang-pwmwrite`. We recommend writing pwmWrite() instead of + analogWrite(). + + This is because PWM is not true analog output (it's not the output + of a `DAC + <http://en.wikipedia.org/wiki/Digital-to-analog_converter>`_\ ), so + the function is very badly named. For instance, **analogWrite() + has nothing to do with** :ref:`lang-analogread`\ , which can be + confusing. + + We provide analogWrite() for the sake of compatibility with Arduino + only. + +.. contents:: Contents + :local: + +.. _lang-analogwrite-compatibility: + +Arduino Compatibility +--------------------- + +There are a few important differences between Arduino's `analogWrite() +<http://arduino.cc/en/Reference/AnalogWrite>`_ and Maple's +:ref:`lang-pwmwrite` that you should keep in mind. In each case, we +have some recommendations you can use to help converting from Arduino +to Maple. + +Difference 1: Duty cycle range is different +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The first and most important difference is that the largest possible +value for the duty cycle is much bigger on the Maple. Using Arduino's +analogWrite(), the duty cycle ranges between 0--255 (always off -- +always on)\ [#fbytemax]_\ . Using Maple's pwmWrite(), the duty cycle +ranges from 0--65,535 by default\ [#fuint16max]_\ . + +This is a good thing! The greater range of values on the Maple gives +you much more precise control over the duty cycle of your PWM output. + +If you're porting code from the Arduino and want a quick-and-dirty +fix, one solution is to :ref:`map <lang-map>` the argument to +analogWrite() into the right range:: + + // Arduino code: + analogWrite(pin, duty); + + // Becomes Maple code: + analogWrite(pin, map(duty, 0, 255, 0, 65535)); + +This will convert values in the range 0-255 to values in the range +0--65,535, which is the correct default range for all of the timers +which control PWM output. See the :ref:`timers reference <timers>` +for more information. + +Another fix is to consult your board's :ref:`pin maps <gpio-pin-maps>` +to find the timer which controls PWM on the pin you're using, then set +that timer's overflow to 255. Subsequent calls to analogWrite() +should work as on the Arduino (with the same loss of precision). +Note, however, that that affects the overflow for the **entire +timer**, so other code relying on that timer (such as any +:ref:`interrupts <lang-hardwaretimer-interrupts>` the timer controls) +will likely need to be modified as well. + +Difference 2: You must use pinMode() to set up PWM +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The second difference is that on the Maple, you **must** set up the pin +for PWM output using :ref:`lang-pinmode`\ , with argument ``PWM``. +This should just be one extra line of code in your +:ref:`lang-setup` function. Example:: + + void setup() { + // set up pin 9 for PWM + pinMode(9, PWM); + } + +This also means that you can't later call :ref:`lang-digitalread` +or :ref:`lang-digitalwrite` on that pin (unless some time in +between, you use pinMode() to reconfigure that pin for ``INPUT`` or +``OUTPUT``; see the :ref:`lang-pinmode` page for more information). + +Difference 3: No PWM on pin 10 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +On the Maple, the pins which support PWM are: 0, 1, 2, 3, 5, 6, 7, 8, +9, 11, 12, 14, 24, 27, and 28 or fifteen pins in total. That's *more* +PWM-capable pins as any Arduino board, but there are differences in +*which* pins support PWM. + +* On **most Arduino boards** (those with the ATmega168 or ATmega328; + this includes the **Arduino Uno**), this function works on pins 3, + 5, 6, 9, 10, and 11, or six pins total. Note that these boards + support PWM on pin 10, while Maple does not. + +* On the **Arduino Mega**, PWM works on pins 2 through 13, or twelve + pins total. Note that this board supports PWM on pins 4, 10, and + 13, while the Maple does not. + +* **Older Arduino boards** with an ATmega8 only support analogWrite() + on pins 9, 10, and 11. Maple does not support PWM on pin 10. + +In all cases, Arduino boards support PWM on pin 10, unlike Maple. We +did our best to make PWM as pin-compatible as possible; however, +circuit layout constraints prevented us from achieving perfect +compatibility. + +The "safest" pins to use for PWM output are pins 9 and 11. These pins +work on any Arduino board and on Maple. The "safe" pins, which work +on most recent Arduino boards, the Arduino Mega and the Maple, are +pins 3, 5, 6, 9, and 11. Thus, if you want your project to be as +portable as possible between Maple and Arduino, we recommend using the +"safest" pins first, then the "safe" pins, then any other pins, as +necessary. + +Difference 4: PWM frequency +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The frequency of the PWM signal (i.e., the frequency of a complete +on/off cycle) on the Arduino is approximately 490 Hz. + +On the Maple, the frequency is configurable, defaulting to about 1100 +Hz, or 1.1 KHz. This is because the PWM frequency is the frequency of +the timer which controls PWM output on the particular pin (\ +:ref:`the PWM tutorial has the details <pwm>`\ ). + +If your application definitely requires Arduino's PWM frequency, then +the steps are: + +1. Figure out which :ref:`timer <lang-hardwaretimer>` controls PWM + output on your pin (\ :ref:`your board's Timer Pin Map + <gpio-pin-maps>` is your friend here). + +2. Let's say it's timer ``n``, where ``n`` is some number. You'll + then need to put "``HardwareTimer timer(n);``" with your variables, + as described in the :ref:`HardwareTimer + <lang-hardwaretimer-getting-started>` reference. + +3. In your :ref:`lang-setup`, put "``timer.setPeriod(2041);``". This + will set the timer's period to approximately 2041 microseconds, + which is a frequency of approximately 490 Hz. + +Be aware that this will change the period for the **entire timer**\ , +and will affect anything else in your program that depends on that +timer. The important examples are :ref:`timer interrupts +<lang-hardwaretimer-interrupts>` and :ref:`PWM +<timers-pwm-conflicts>`\ . + +See Also +-------- + +- :ref:`pwm` +- :ref:`lang-pwmwrite` +- :ref:`BOARD_NR_PWM_PINS <lang-board-values-nr-pwm-pins>` +- :ref:`boardPWMPins <lang-board-values-pwm-pins>` + +.. rubric:: Footnotes + +.. [#fbytemax] This is because the value for the duty cycle on Arduino + must fit in 1 byte of memory, and an unsigned (i.e., nonnegative) + integer with size 1 byte can hold the values between 0 and 255. + +.. [#fuint16max] This is because the value for the duty cycle on the + Maple uses 2 bytes of memory, and an unsigned (i.e., nonnegative) + integer with size 2 bytes can hold the values between 0 and 65,535. + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/api/assert.rst b/docs/source/lang/api/assert.rst new file mode 100644 index 0000000..76330b6 --- /dev/null +++ b/docs/source/lang/api/assert.rst @@ -0,0 +1,30 @@ +.. highlight:: cpp + +.. _lang-assert: + +``ASSERT(...)`` +=============== + +ASSERT() can be very useful for basic program debugging. It accepts a +boolean; for example:: + + ASSERT(state == WAIT); + +Zero is false and any other number is true. If the boolean is true, +the assertion passes and the program continues as usual. If it is +false, the assertion fails: the program is halted, debug information +is printed to USART2, and the status LED begins to throb (it's +noticeably different from blinking). The debug information is printed +at 9600 baud and consists of the filename and line number where the +ASSERT() failed. + +Including assertions in a program increases the program size. When +using libmaple **from the command line only**, they can be disabled by +making the definition :: + + #define DEBUG_LEVEL DEBUG_NONE + +before including either wirish.h or libmaple.h. In this case, all +assertions will pass without any lost clock cycles. Note that this +will **not work in the IDE**; even with this definition, assertions +will still be enabled. diff --git a/docs/source/lang/api/attachinterrupt.rst b/docs/source/lang/api/attachinterrupt.rst new file mode 100644 index 0000000..58e4764 --- /dev/null +++ b/docs/source/lang/api/attachinterrupt.rst @@ -0,0 +1,114 @@ +.. highlight:: cpp + +.. _lang-attachinterrupt: + +attachInterrupt() +================= + +Used to specify a function to call when an :ref:`external interrupt +<external-interrupts>` occurs. + +.. contents:: Contents + :local: + +Library Documentation +--------------------- + +.. FIXME [doxygenfunction] once Breathe knows how to get the correct +.. attachInterupt (right now it's copying from HardwareTimer), replace +.. with a doxygenfunction directive + +.. cpp:function:: void attachInterrupt(uint8 pin, voidFuncPtr handler, ExtIntTriggerMode mode) + + Registers an interrupt handler on a pin. + + The interrupt will be triggered on a given transition on the pin, + as specified by the mode parameter. The handler runs in interrupt + context. The new handler will replace whatever handler is + currently registered for the pin, if any. + + *Parameters* + + - ``pin`` - Maple pin number + + - ``handler`` - Function to run upon external interrupt trigger. + The handler should take no arguments, and have void return type. + + - ``mode`` - Type of transition to trigger on, e.g. falling, + rising, etc. + +.. doxygenenum:: ExtIntTriggerMode + +.. doxygentypedef:: voidFuncPtr + +.. note:: + + You should set the :ref:`pin mode <lang-pinmode>` of your desired + pin to an input mode (e.g. ``INPUT``, ``INPUT_PULLUP``, + ``INPUT_PULLDOWN``). + +Discussion +---------- + +Because the function will run in interrupt context, inside of it, +:ref:`lang-delay` won't work, and the value returned by +:ref:`lang-millis` will not increment. Serial data received while in +the function may be lost. You should declare as ``volatile`` any +global variables that you modify within the attached function. + +There are some limits you should be aware of if you're using +``attachInterrupt()`` with more than one pin; the :ref:`External +Interrupts <external-interrupts-exti-line>` page has more information. + +Example +------- + +The following example blinks the LED any time pin 0 changes from +``HIGH`` to ``LOW`` or vice versa. :: + + volatile int state = LOW; // must declare volatile, since it's + // modified within the blink() handler + + void setup() { + pinMode(BOARD_LED_PIN, OUTPUT); + pinMode(0, INPUT); + attachInterrupt(0, blink, CHANGE); + } + + void loop() { + digitalWrite(BOARD_LED_PIN, state); + } + + void blink() { + if (state == HIGH) { + state = LOW; + } else { // state must be LOW + state = HIGH; + } + } + +In this example, the function ``blink()`` is the interrupt handler. +Whenever the state on pin 0 changes, ``blink()`` gets called. It +reacts to the change by changing the ``state`` variable to ``LOW`` if +it is ``HIGH``, and to ``HIGH`` if it is ``LOW``. It then exits, +letting the board get back to calling ``loop()``. Since ``loop()`` +sets the LED pin to whatever ``state`` is, changing the voltage on pin +0 will toggle the LED. + +Arduino Compatibility +--------------------- + +Most Arduino boards have two external interrupts: numbers 0 (on +digital pin 2) and 1 (on digital pin 3). The Arduino Mega has an +additional four: numbers 2 (pin 21), 3 (pin 20), 4 (pin 19), and 5 +(pin 18). On the Maple, you don't have to remember which interrupt +number goes with which pin -- just tell ``attachInterrupt()`` the pin +you want. + +See Also +-------- + +- :ref:`lang-detachinterrupt` +- :ref:`external-interrupts` + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/api/bit.rst b/docs/source/lang/api/bit.rst new file mode 100644 index 0000000..3df042c --- /dev/null +++ b/docs/source/lang/api/bit.rst @@ -0,0 +1,38 @@ +.. _lang-bit: + +bit() +===== + +(Macro) Computes the value of an (unsigned) integer with the specified +bit set (``bit(0)`` is 1, ``bit(1)`` is 2, ``bit(2)`` is 4, then 8, +16, 32, etc.). + +Syntax +------ + +``bit(n)`` + +Parameters +---------- + +* **n** the bit to set. + +Value +----- + +The value of an integer with the given bit set. + +Arduino Compatibility +--------------------- + +The Maple implementation of ``bit()`` is compatible with Arduino. + +See Also +-------- + +- :ref:`lang-bitread` +- :ref:`lang-bitwrite` +- :ref:`lang-bitset` +- :ref:`lang-bitclear` + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/api/bitclear.rst b/docs/source/lang/api/bitclear.rst new file mode 100644 index 0000000..f487059 --- /dev/null +++ b/docs/source/lang/api/bitclear.rst @@ -0,0 +1,39 @@ +.. _lang-bitclear: + +bitClear() +========== + +(Macro) Clears (writes a 0 to) a bit of a numeric variable. + +Syntax +------ + +``bitClear(x, n)`` + +Parameters +---------- + +* **x** the numeric variable whose bit to clear + +* **n** which bit to clear, starting at 0 for the least-significant + (rightmost) bit + +Returns +------- + +Nothing. + +Arduino Compatibility +--------------------- + +The Maple implementation of ``bitClear()`` is compatible with Arduino. + +See Also +-------- + +- :ref:`bit <lang-bit>`\ () +- :ref:`bitRead <lang-bitread>`\ () +- :ref:`bitWrite <lang-bitwrite>`\ () +- :ref:`bitSet <lang-bitset>`\ () + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/api/bitread.rst b/docs/source/lang/api/bitread.rst new file mode 100644 index 0000000..fd9fbbe --- /dev/null +++ b/docs/source/lang/api/bitread.rst @@ -0,0 +1,39 @@ +.. _lang-bitread: + +bitRead() +========= + +(Macro) Gets the value of a bit in a number. + +Syntax +------ + +``bitRead(x, n)`` + +Parameters +---------- + +* **x** the number from which to read the bit. + +* **n** which bit to read, starting at 0 for the least-significant + (rightmost) bit + +Value +----- + +The value of the bit (0 or 1). + +Arduino Compatibility +--------------------- + +The Maple implementation of ``bitRead`` is compatible with Arduino. + +See Also +-------- + +- :ref:`lang-bit` +- :ref:`lang-bitwrite` +- :ref:`lang-bitset` +- :ref:`lang-bitclear` + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/api/bitset.rst b/docs/source/lang/api/bitset.rst new file mode 100644 index 0000000..83ab5f8 --- /dev/null +++ b/docs/source/lang/api/bitset.rst @@ -0,0 +1,39 @@ +.. _lang-bitset: + +bitSet() +======== + +(Macro) Sets (writes a 1 to) a bit of a numeric variable. + +Syntax +------ + +``bitSet(x, n)`` + +Parameters +---------- + +* **x** the numeric variable whose bit to set + +* **n** which bit to set, starting at 0 for the least-significant + (rightmost) bit + +Value +----- + +None. + +Arduino Compatibility +--------------------- + +The Maple implementation of bitSet is compatible with Arduino. + +See Also +-------- + +- :ref:`lang-bit` +- :ref:`lang-bitread` +- :ref:`lang-bitwrite` +- :ref:`lang-bitclear` + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/api/bitwrite.rst b/docs/source/lang/api/bitwrite.rst new file mode 100644 index 0000000..6106545 --- /dev/null +++ b/docs/source/lang/api/bitwrite.rst @@ -0,0 +1,45 @@ +.. highlight:: cpp + +.. _lang-bitwrite: + +bitWrite() +========== + +(Macro) Writes a bit of a numeric variable. + +Syntax +------ + +:: + + bitWrite(x, n, b) + +Parameters +---------- + +**x**: the numeric variable whose bit to write. + +**n**: which bit of the number to write, starting at 0 for the +least-significant (rightmost) bit. + +**b**: the value to write to the bit (0 or 1). + +Returns +------- + +Nothing. + +Arduino Compatibility +--------------------- + +Maple's implementation of ``bitWrite()`` is compatible with Arduino. + +See Also +-------- + +- :ref:`bit() <lang-bit>` +- :ref:`bitRead() <lang-bitRead>` +- :ref:`bitSet() <lang-bitSet>` +- :ref:`bitClear() <lang-bitClear>` + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/api/board-values.rst b/docs/source/lang/api/board-values.rst new file mode 100644 index 0000000..d944c8d --- /dev/null +++ b/docs/source/lang/api/board-values.rst @@ -0,0 +1,189 @@ +.. highlight:: cpp + +.. _lang-board-values: + +Board-Specific Values +===================== + +There are a number of board-specific values: constants or variables +which are different depending on which LeafLabs board you have. The +exact values for each board are given in your :ref:`board's hardware +documentation <index-boards>`. + +This page lists and documents the board-specific values. You should +use these when appropriate in your own programs. This will help make +it easier to share your code with other people who have different +boards. Some example usages are given :ref:`below +<lang-board-values-examples>`. + +.. contents:: Contents + :local: + +Constants +--------- + +- ``CYCLES_PER_MICROSECOND``: Number of CPU cycles per microsecond on + your board. + +- ``CLOCK_SPEED_MHZ``: Clock speed of your board, in megahertz + (MHz). This is the same as ``CYCLES_PER_MICROSECOND``. + +- ``CLOCK_SPEED_HZ``: Clock speed of your board, in hertz (Hz). This + is the same as ``CLOCK_SPEED_MHZ`` × 1,000,000. + +- ``SYSTICK_RELOAD_VAL``: Value used when reloading the :ref:`systick` + timer's counter [#fmillis]_. + +.. _lang-board-values-but: + +- ``BOARD_BUTTON_PIN``: Pin connected to the built-in button (labeled + "BUT" on your board's silkscreen). + +.. _lang-board-values-led: + +- ``BOARD_LED_PIN``: Pin connected to the built-in LED. + +- ``BOARD_NR_GPIO_PINS``: Total number of :ref:`GPIO pins <gpio>` that + are broken out to headers. Some of these might already be connected + to external hardware (like the built-in LED and button). To find + out if a pin is in use, see :ref:`boardUsesPin() + <lang-boardusespin>` (and also :ref:`boardUsedPins + <lang-board-values-used-pins>`). + +.. _lang-board-values-nr-pwm-pins: + +- ``BOARD_NR_PWM_PINS``: Total *number* of GPIO pins that can be used + for :ref:`PWM <pwm>`. The actual *pins* that can do PWM are in the + :ref:`boardPWMPins <lang-board-values-pwm-pins>` array. + +.. _lang-board-values-nr-adc-pins: + +- ``BOARD_NR_ADC_PINS``: Total number of GPIO pins that can be used + for :ref:`analog-to-digital conversion <adc>`. The actual pins that + can do ADC conversion are in the :ref:`boardADCPins + <lang-board-values-adc-pins>` array. + +.. _lang-board-values-nr-used-pins: + +- ``BOARD_NR_USED_PINS``: Total number of GPIO pins that are already + connected to some external hardware (like a built-in LED) on the + board. The actual pins that that are already used are in the + :ref:`boardUsedPins <lang-board-values-used-pins>` array. To see if + a pin is already in use, use the :ref:`boardUsesPin() + <lang-boardusespin>` function. + +.. _lang-board-values-usart: + +- :ref:`USART <usart>` (serial port) related constants: + + * ``BOARD_USART1_TX_PIN``, ``BOARD_USART2_TX_PIN``, ``BOARD_USART3_TX_PIN``: + TX pins for the 3 USARTS. + + * ``BOARD_USART1_RX_PIN``, ``BOARD_USART2_RX_PIN``, ``BOARD_USART3_RX_PIN``: + RX pins for the 3 USARTS. + + * ``BOARD_UART4_TX_PIN``, ``BOARD_UART5_TX_PIN``: TX pins for + UARTs 4 and 5 (high-density boards like Maple Native only). + + * ``BOARD_UART4_RX_PIN``, ``BOARD_UART5_RX_PIN``: RX pins for + UARTs 4 and 5 (high-density boards like Maple Native only). + + * ``BOARD_NR_USARTS``: Number of serial ports on the board. This + number includes UARTs 4 and 5 if they are available. + +- :ref:`SPI <spi>` related constants: + + * ``BOARD_SPI1_NSS_PIN``, ``BOARD_SPI1_MOSI_PIN``, + ``BOARD_SPI1_MISO_PIN``, ``BOARD_SPI1_SCK_PIN``: SPI1 + peripheral's NSS, MOSI, MISO, and SCK pins, respectively. + + * ``BOARD_SPI2_NSS_PIN``, ``BOARD_SPI2_MOSI_PIN``, + ``BOARD_SPI2_MISO_PIN``, ``BOARD_SPI2_SCK_PIN``: SPI2 + peripheral's NSS, MOSI, MISO, and SCK pins, respectively. + + * ``BOARD_SPI3_NSS_PIN``, ``BOARD_SPI3_MOSI_PIN``, + ``BOARD_SPI3_MISO_PIN``, ``BOARD_SPI3_SCK_PIN``: SPI3 + peripheral's NSS, MOSI, MISO, and SCK pins, respectively + (available on high-density devices like Maple Native and Maple + RET6 edition only). + + * ``BOARD_NR_SPI``: Number of SPI peripherals on the board. + +.. _lang-board-values-debug: + +- Debug (JTAG, SW-Debug) related constants: ``BOARD_JTMS_SWDIO_PIN``, + ``BOARD_JTCK_SWCLK_PIN``, ``BOARD_JTDI_PIN``, ``BOARD_JTDO_PIN``, + and ``BOARD_NJTRST_PIN``. + + These constants are the pin numbers for :ref:`GPIOs <gpio>` used by + the :ref:`jtag` and Serial-Wire Debug peripherals. Except for the + Maple Mini, these pins are usually reserved for special purposes by + default (i.e., they are in :ref:`boardUsedPins + <lang-board-values-used-pins>`). However, they can be used as + ordinary GPIOs if you call the :ref:`lang-disabledebugports` + function. (Be careful with this on the Maple and Maple RET6 + Edition, as writing to ``BOARD_NJTRST_PIN`` :ref:`may cause your + board to reset <maple-nrst-pb4>`\ !). + +.. _lang-board-values-pwm-pins: + +.. _lang-board-values-adc-pins: + +.. _lang-board-values-used-pins: + +Pin Arrays +---------- + +Some :ref:`arrays <lang-array>` of pin numbers are available which you +can use to find out certain important information about a given pin. + +- ``boardPWMPins``: Pin numbers of each pin capable of :ref:`PWM + <pwm>` output, using :ref:`pwmWrite() <lang-pwmwrite>`. The total + number of these pins is :ref:`BOARD_NR_PWM_PINS + <lang-board-values-nr-pwm-pins>`. + +- ``boardADCPins``: Pin numbers of each pin capable of :ref:`ADC + <adc>` conversion, using :ref:`analogRead() <lang-analogread>`. The + total number of these pins is :ref:`BOARD_NR_ADC_PINS + <lang-board-values-nr-adc-pins>`. + +- ``boardUsedPins``: Pin numbers of each pin that, by default, is used + for some special purpose by the board. The total number of these + pins is :ref:`BOARD_NR_USED_PINS <lang-board-values-nr-used-pins>`. + To check if a pin is used for a special purpose, use + :ref:`boardUsesPin() <lang-boardusespin>`. + +.. _lang-board-values-examples: + +Examples +-------- + +:ref:`BOARD_LED_PIN <lang-board-values-led>` On the Maple, the +built-in LED is connected to pin 13. On the Maple Mini, however, it +is connected to pin 33. You can write a "blinky" program that works +on both boards using :ref:`this example <lang-toggleled-example>`. + +:ref:`BOARD_BUTTON_PIN <lang-board-values-but>`: On the Maple, the +built-in button is connected to pin 38. On the Maple Mini, however, +it is connected to pin 32. :ref:`This example +<lang-waitforbuttonpress-example>` shows how you can write a program +that prints a message whenever the button is pressed which will work +on all LeafLabs boards. + +See Also +-------- + +- :ref:`lang-boardusespin` +- :ref:`lang-isbuttonpressed` +- :ref:`lang-waitforbuttonpress` +- :ref:`lang-pinmode` +- :ref:`lang-toggleled` +- :ref:`lang-analogread` +- :ref:`lang-pwmwrite` +- :ref:`lang-enabledebugports` +- :ref:`lang-disabledebugports` + +.. rubric:: Footnotes + +.. [#fmillis] In order for :ref:`lang-millis` to work properly, this + must be ``CYCLES_PER_MICROSECOND`` × 1,000 - 1. diff --git a/docs/source/lang/api/boardusespin.rst b/docs/source/lang/api/boardusespin.rst new file mode 100644 index 0000000..126c4a0 --- /dev/null +++ b/docs/source/lang/api/boardusespin.rst @@ -0,0 +1,27 @@ +.. highlight:: cpp + +.. _lang-boardusespin: + +boardUsesPin() +============== + +Each LeafLabs board connects some pins to external hardware. The most +important examples of this are the pins connected to the built-in LED +and button. You can check if a board uses a particular pin using this +function. + +Library Documentation +--------------------- + +.. doxygenfunction:: boardUsesPin + +See Also +-------- + +- :ref:`Board-specific values <lang-board-values>` +- :ref:`boardUsedPins <lang-board-values-used-pins>` +- :ref:`BOARD_LED_PIN <lang-board-values-led>` +- :ref:`toggleLED() <lang-toggleled>` +- :ref:`BOARD_BUTTON_PIN <lang-board-values-but>` +- :ref:`isButtonPressed() <lang-isbuttonpressed>` +- :ref:`waitForButtonPress() <lang-waitforbuttonpress>` diff --git a/docs/source/lang/api/constants.rst b/docs/source/lang/api/constants.rst new file mode 100644 index 0000000..6f69dfe --- /dev/null +++ b/docs/source/lang/api/constants.rst @@ -0,0 +1,318 @@ +.. _lang-constants: + +Constants +========= + +Constants are like predefined variables, whose values can't +change. They are used to make the programs easier to read and modify. +This page describes the most commonly used constants. + +.. contents:: Contents + :local: + +.. _lang-constants-bool: + +Boolean Constants +----------------- + +There are two constants used to represent truth and falsity: ``true``, +and ``false``. + +.. _lang-constants-false: + +false +^^^^^ + +``false`` is the false ``bool`` value. An integer which is 0 evaluates +to ``false`` as a boolean. + +.. _lang-constants-true: + +true +^^^^ + +``true`` is the true ``bool`` value. As an integer, ``true`` is often +said to be 1. This is correct in the sense that ``true`` evaluates to +1 as an integer. However, any integer which is *non-zero* is ``true`` +as a :ref:`bool <lang-booleanvariables>`. So -1, 2 and -200 are all +"true", in the sense that these numbers are treated the same as +``true`` in a boolean context. + +Note that the ``true`` and ``false`` constants are typed in lowercase; +unlike e.g. ``HIGH``, ``LOW``, ``INPUT``, and ``OUTPUT`` (which are +described below). + +.. _lang-pin-levels: + +Pin Levels: HIGH and LOW +------------------------ + +When reading or writing to a digital pin there are only two possible +values a pin can be set to: ``HIGH`` and ``LOW``. + +.. _lang-constants-high: + +HIGH +^^^^ + +The meaning of ``HIGH`` (in reference to a pin) is somewhat different +depending on whether the pin is set to ``INPUT`` or ``OUTPUT``. When a +pin is configured as an ``INPUT`` (using :ref:`pinMode() +<lang-pinmode>`), and read with :ref:`digitalRead() +<lang-digitalread>`, the microcontroller will report ``HIGH`` if a +voltage of 3 volts or more is present at the pin. + +When a pin is configured to ``OUTPUT`` with ``pinMode()``, and set to +``HIGH`` with :ref:`digitalWrite() <lang-digitalwrite>`, the pin is at +3.3 volts. In this state it can *source* current, e.g. light an LED +that is connected through a series resistor to ground, or to another +pin configured as an output and set to ``LOW``. + +.. _lang-constants-low: + +LOW +^^^ + +The meaning of ``LOW`` also has a different meaning depending on +whether a pin is set to ``INPUT`` or ``OUTPUT``. When a pin is +configured as an ``INPUT`` with :ref:`pinMode() <lang-pinmode>`, and +read with :ref:`digitalRead() <lang-digitalread>`, the microcontroller +will report ``LOW`` if a voltage of 2 volts or less is present at the +pin. + +When a pin is configured to ``OUTPUT`` with ``pinMode()``, and set to +``LOW`` with :ref:`digitalWrite() <lang-digitalwrite>`, the +microcontroller will attempt to keep that pin's voltage at 0 V. In this +state it can *sink* current, e.g. light an LED that is connected +through a series resistor to +3.3 V, or to another pin configured as an +output, and set to ``HIGH``. + +Pin Modes +--------- + +Digital pins can be used in a variety of modes. The basic modes, +``INPUT`` and ``OUTPUT``, have been introduced above. Changing a pin +from ``INPUT`` TO ``OUTPUT`` with :ref:`pinMode() <lang-pinmode>` +drastically changes the electrical behavior of the pin. + +This section describes the basic digital pin modes (``INPUT`` and +``OUTPUT``) only. For a detailed description of all possible pin +modes, see the :ref:`pinMode() <lang-pinmode>` reference page. + +.. _lang-constants-input: + +INPUT +^^^^^ + +Pins configured as ``INPUT`` are said to be in a *high-impedance +state*. One way of explaining this is that pins configured as +``INPUT`` make very few demans on circuit that they are connected +to. This makes them useful for reading a sensor, but not powering an +LED. + +.. _lang-constants-output: + +OUTPUT +^^^^^^ + +Pins configured as ``OUTPUT`` with :ref:`pinMode() <lang-pinmode>` are +said to be in a low-impedance state. This means that they can provide +a substantial amount of current to other circuits. Pins can source +(provide positive current) or sink (provide negative current) up to 50 +mA (milliamps) of current to other devices/circuits. This makes them +useful for powering LEDs, but useless for reading sensors. + +Pins configured as outputs can also be damaged or destroyed if short +circuited to either ground or power supplies. The amount of current +provided by a pin is also not enough to power most relays or motors, +and some interface circuitry will be required. + +.. _lang-constants-integers: + +Integer Constants +----------------- + +Integer constants are numbers used directly in a sketch, like +``123``. By default, an integer constant is treated as a (signed) +:ref:`int <lang-int>`, but you can change this with the U and L +modifiers (see :ref:`below <lang-constants-integers-u-l>`). You can +specify negative numbers by putting a minus sign in front, like +``-123``. + +Normally, integer constants are treated as base 10 (decimal) integers, +but special notation (formatters) may be used to enter numbers in +other bases. These are explained in the following table: + +.. list-table:: + :header-rows: 1 + + * - Base + - Example + - Formatter + - Comment + + * - 10 (decimal) + - ``123`` + - None + - + + * - 2 (binary) + - ``0b1111011`` + - Leading "0b" + - GCC extension; not standard C++ + + * - 8 (octal) + - ``0173`` + - Leading "0" + - Characters 0-7 valid + + * - 16 (hexadecimal) + - ``0x7B`` + - Leading "0x" + - Characters 0-9, A-F (or a-f) valid + +Binary constants (like ``B1111011``) for values between 0 and 255 are +supported for compatibility with Arduino only. You shouldn't use them +in new programs. + +.. _lang-constants-integers-dec: + +**Decimal** is base 10. This is the common number system we learn in +school. Integer literals without other prefixes are assumed to be in +decimal format. + +For example, the decimal literal ``101`` is one hundred and one: 1×10\ +:sup:`2` + 0×10\ :sup:`1` + 1×10\ :sup:`0` = 101. + +.. _lang-constants-integers-bin: + +**Binary** is base two. Only characters 0 and 1 are valid. Binary +literals are indicated by the prefix ``0b``. + +For example, the binary literal ``0b101`` is five: 1×2\ :sup:`2` + +0×2\ :sup:`1` + 1×2\ :sup:`0` = 5. + +.. _lang-constants-integers-oct: + +**Octal** is base eight. Only characters 0 through 7 are valid. Octal +literals are indicated by the prefix ``0``. + +For example, the octal literal ``0101`` is sixty five: 1×8\ :sup:`2` + +0×8\ :sup:`1` + 1×8\ :sup:`0` = 65. + +.. warning:: Bugs sometimes result by (unintentionally) including a + leading "0" before an integer literal, which makes the compiler + treat it as an octal number. + +.. _lang-constants-integers-hex: + +**Hexadecimal** (or "hex") is base sixteen. Valid characters are 0 +through 9 and letters A through F; A has the value 10, B is 11, up to +F, which is 15. Hex values are indicated by the prefix ``0x``. A-F +can be typed in upper or lower case (a-f). + +For example, the hexadecimal constant ``0x101`` is two hundred fifty +seven: 1×16\ :sup:`2` + 0×16\ :sup:`1` + 1×16\ :sup:`0` = 257. + +The hexadecimal constant ``0xCF2`` is three thousand, three hundred +fourteen: 12×16\ :sup:`2` + 15×16\ :sup:`1` + 2×16\ :sup:`0` = 3314. + +(Remember that in hex, ``A`` means 10, and counting up, ``B``\ =11, so +``C``\ =12 and ``F``\ =15). + +.. _lang-constants-integers-u-l: + +U and L Suffixes +^^^^^^^^^^^^^^^^ + +By default, an integer constant is treated as an :ref:`int <lang-int>` +(and must be in the int type's :ref:`range limits +<lang-int-overflow>`). To specify an integer constant with another +data type, follow it with: + +- a ``u`` or ``U`` to interpret the constant as an unsigned value. + For example, ``33U`` is an :ref:`unsigned int <lang-unsignedint>`. + +- an ``l`` or ``L`` to interpret the constant as a long value. For + example, ``100000L`` is a :ref:`long <lang-long>`. On the Maple, + ``long`` is just a synonym for ``int``. + +- a ``ul`` or ``UL`` to do both. For example, ``32767UL`` is an + :ref:`unsigned long <lang-unsignedlong>`. On the Maple, ``unsigned + long`` is just a synonym for ``unsigned int``. + +- an ``ll`` or ``LL`` to interpret the constant as a :ref:`long long + <lang-longlong>` value. + +- a ``ull`` or ``ULL`` to interpret the constant as an :ref:`unsigned + long long <lang-unsignedlonglong>`. + +.. _lang-constants-fp: + +Floating-Point Constants +------------------------ + +A floating point constant is any number which includes a decimal +point. For instance, ``3.0`` is a floating-point constant for the +number 3. By default, a floating-point constant is a :ref:`double +<lang-double>`. In order for the constant to be interpreted as a +:ref:`float <lang-float>`, you can write ``f`` directly after it. For +example, ``3.0f`` is a floating-point constant with type ``float``. + +Floating point constants can also be expressed in a variety of +scientific notation. ``E`` and ``e`` are both accepted as valid +exponent indicators. Some examples are given in the following table: + + +.. list-table:: + :header-rows: 1 + + * - Floating-point constant + - Evaluates to + - Alternate expression + + * - ``10.0`` + - 10 + - + + * - ``2.34E5`` + - 2.34×10\ :sup:`5` + - ``234000.0`` + + * - ``67e-12`` + - 67.0×10\ :sup:`-12` + - ``0.000000000067`` + +.. _lang-constants-board: + +Board-Specific Constants +------------------------ + +There are several :ref:`board-specific constants <lang-board-values>` +whose value depends on which LeafLabs board you have. If you use +them, it will help make sure that your code will work well on all +LeafLabs boards, not just the one you have. This will make it easier +to share your code with others. + +For example, the pin number connected to the board's built-in LED is +different on the different boards, but the board-specific constant +:ref:`BOARD_LED_PIN <lang-board-values-led>` will always be the +correct value for each board. + +See Also +-------- + +- :ref:`pinMode() <lang-pinmode>` +- :ref:`Boolean Variables <lang-booleanvariables>` +- :ref:`#define <lang-define>` +- :ref:`int <lang-int>` +- :ref:`unsigned int <lang-unsignedint>` +- :ref:`long <lang-long>` +- :ref:`unsigned long <lang-unsignedlong>` +- :ref:`long long <lang-longlong>` +- :ref:`unsigned long long <lang-unsignedlonglong>` +- :ref:`float <lang-float>` +- :ref:`double <lang-double>` +- :ref:`Board-Specific Values <lang-board-values>` + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/api/constrain.rst b/docs/source/lang/api/constrain.rst new file mode 100644 index 0000000..28af1e3 --- /dev/null +++ b/docs/source/lang/api/constrain.rst @@ -0,0 +1,68 @@ +.. highlight:: cpp + +.. _lang-constrain: + +constrain() +=========== + +(Macro) Constrains a number to be within a range. + +Syntax +------ + +:: + + constrain(x, a, b) + + +Parameters +---------- + +**x**: the number to constrain + +**a**: the lower end of the range + +**b**: the upper end of the range + +Returns +------- + +**x**: if **x** is between **a** and **b** + +**a**: if **x** is less than **a** + +**b**: if **x** is greater than **b** + +Example +------- + +:: + + // limits range of sensor values to between 10 and 150: + sensVal = constrain(sensVal, 10, 150); + + +Warning +------- + +Because of the way ``constrain()`` is implemented, avoid using other +functions or causing side effects inside the parentheses, as it may +lead to incorrect results:: + + constrain(x,a++,b); // avoid this - yields incorrect results + + constrain(x,a,b); // use this instead- + a++; // keep other math outside constrain() + +Arduino Compatibility +--------------------- + +Maple's implementation of ``constrain()`` is compatible with Arduino. + +See Also +-------- + +- :ref:`min() <lang-min>` +- :ref:`max() <lang-max>` + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/api/cos.rst b/docs/source/lang/api/cos.rst new file mode 100644 index 0000000..c340f09 --- /dev/null +++ b/docs/source/lang/api/cos.rst @@ -0,0 +1,30 @@ +.. _lang-cos: + +cos() +===== + +Calculates the cosine of an angle. + +Library Documentation +--------------------- + +.. doxygenfunction:: cos + +Arduino Compatibility +--------------------- + +The Maple ``cos()`` implementation is compatible with Arduino. + +Note that the Maple implementation comes from `newlib +<http://sourceware.org/newlib/>`_\ , while Arduino's is that of +`avr-libc <http://avr-libc.nongnu.org/>`_\ . + +See Also +-------- + +- :ref:`sin() <lang-sin>` +- :ref:`tan() <lang-tan>` +- :ref:`float <lang-float>` +- :ref:`double <lang-double>` + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/api/delay.rst b/docs/source/lang/api/delay.rst new file mode 100644 index 0000000..30bd436 --- /dev/null +++ b/docs/source/lang/api/delay.rst @@ -0,0 +1,69 @@ +.. highlight:: cpp + +.. _lang-delay: + +delay() +======= + +Pauses the program for at least a given number of milliseconds. (There +are 1000 milliseconds in a second.) + +Library Documentation +--------------------- + +.. doxygenfunction:: delay + + +Discussion +---------- + +While it is easy to create a blinking LED with the ``delay()`` +function, and many sketches use short delays for such tasks as switch +debouncing, the use of ``delay()`` in a sketch has significant +drawbacks. No other reading of sensors, mathematical calculations, or +pin manipulation can go on during the delay function, so in effect, it +brings most other activity to a halt. For alternative approaches to +controlling timing see the :ref:`millis() <lang-millis>` function +and the "Blink Without Delay" sketch cited :ref:`below +<lang-delay-seealso>`\ . More knowledgeable programmers usually +avoid the use of ``delay()`` for timing of events longer than tens of +milliseconds, unless the sketch is very simple. + +Certain things *do* go on while the ``delay()`` function is +controlling the STM32 chip, however, because the delay function does +not disable interrupts. Serial communication that appears at the RX +pin is recorded, PWM (see :ref:`pwmWrite() <lang-pwmwrite>`\ ) values +and pin states are maintained, and :ref:`interrupts +<lang-attachinterrupt>` will work as they should. + + +Example +------- + +:: + + void setup() { + // set up the built-in LED pin for output: + pinMode(BOARD_LED_PIN, OUTPUT); + } + + void loop() { + digitalWrite(BOARD_LED_PIN, HIGH); // sets the LED on + delay(1000); // waits for a second + digitalWrite(BOARD_LED_PIN, LOW); // sets the LED off + delay(1000); // waits for a second + } + +.. _lang-delay-seealso: + +See Also +-------- + +- :ref:`millis() <lang-millis>` +- :ref:`micros() <lang-micros>` +- :ref:`delayMicroseconds() <lang-delayMicroseconds>` +- (Arduino) `Blink Without Delay + <http://arduino.cc/en/Tutorial/BlinkWithoutDelay>`_ example (works + unmodified on Maple) + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/api/delaymicroseconds.rst b/docs/source/lang/api/delaymicroseconds.rst new file mode 100644 index 0000000..7078660 --- /dev/null +++ b/docs/source/lang/api/delaymicroseconds.rst @@ -0,0 +1,62 @@ +.. highlight:: cpp + +.. _lang-delaymicroseconds: + +delayMicroseconds() +=================== + +Pauses the program for the amount of time (in microseconds) +specified as parameter. There are a thousand microseconds in a +millisecond, and a million microseconds in a second. + +Library Documentation +--------------------- + +.. doxygenfunction:: delayMicroseconds + + +Example +------- + +The following example configures pin number 8 to work as an output +pin, and sends a train of pulses with a period of roughly 100 +microseconds:: + + int outPin = 8; + + void setup() { + pinMode(outPin, OUTPUT); // sets the digital pin as output + } + + void loop() { + digitalWrite(outPin, HIGH); // sets the pin on + delayMicroseconds(50); // pauses for 50 microseconds + digitalWrite(outPin, LOW); // sets the pin off + delayMicroseconds(50); // pauses for 50 microseconds + } + + +Caveats and Known Issues +------------------------ + +The longest time ``delayMicroseconds()`` can delay is bounded by its +argument type and the STM32 clock rate to be (2^32 - 1) / 12 +microseconds, or less than 6 minutes. For longer pauses, use of +:ref:`lang-delay` is possible. + +Arduino Compatibility +--------------------- + +While we have made every effort we could to ensure that the timing of +``delayMicroseconds()`` is as accurate as possible, we cannot +guarantee it will behave as the Arduino implementation down to the +microsecond, especially for smaller values of ``us``. + +See Also +-------- + +- :ref:`millis <lang-millis>` +- :ref:`micros <lang-micros>` +- :ref:`delay <lang-delay>` + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/api/detachinterrupt.rst b/docs/source/lang/api/detachinterrupt.rst new file mode 100644 index 0000000..6eb8e53 --- /dev/null +++ b/docs/source/lang/api/detachinterrupt.rst @@ -0,0 +1,43 @@ +.. _lang-detachinterrupt: + +detachInterrupt() +================= + +Used to disable an interrupt specified with +:ref:`lang-attachinterrupt`\ . + +Library Documentation +--------------------- + +.. FIXME [Breathe] once we can get the correct detachInterrupt(), +.. replace with doxygenfunction. + +.. cpp:function:: void detachInterrupt(uint8 pin) + + Disable any registered external interrupt on the given pin. + + *Parameters* + + - ``pin`` Maple pin number + +Arduino Compatibility +--------------------- + +There is one important difference between the Maple version of +detachInterrupt and the Arduino version. On the Maple, the argument +to ``detachInterrupt()`` is the *pin* on which the interrupt is +attached, while on the Arduino, the argument is the *interrupt +number*, which is different from the pin the interrupt is enabled on. + +If you're calling this function, you've already called +:ref:`lang-attachinterrupt` to set up your interrupt handler, so +just call ``detachInterrupt()`` with the same pin argument you gave to +``attachInterrupt()``. + +See Also +-------- + +- :ref:`attachInterrupt() <lang-attachInterrupt>` +- :ref:`external-interrupts` + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/api/digitalread.rst b/docs/source/lang/api/digitalread.rst new file mode 100644 index 0000000..03ccd7f --- /dev/null +++ b/docs/source/lang/api/digitalread.rst @@ -0,0 +1,51 @@ +.. highlight:: cpp + +.. _lang-digitalread: + +digitalRead() +============= + +Reads the value from a specified digital pin, either :ref:`HIGH +<lang-constants-high>` or :ref:`LOW <lang-constants-low>`. + +Library Documentation +--------------------- + +.. doxygenfunction:: digitalRead + +Discussion +---------- + +If the pin isn't connected to anything, ``digitalRead()`` can return +either HIGH or LOW (and this will change in a way that seems random). + +Example +------- + +The following example turns the LED on or off when the button is pressed:: + + void setup() { + pinMode(BOARD_LED_PIN, OUTPUT); + pinMode(BOARD_BUTTON_PIN, INPUT); + } + + void loop() { + int val = digitalRead(BOARD_BUTTON_PIN); // reads the input pin + togglePin(BOARD_LED_PIN); + } + +Arduino Compatibility +--------------------- + +The Maple version of ``digitalRead()`` is compatible with Arduino. + +See Also +-------- + +- :ref:`BOARD_BUTTON_PIN <lang-board-values-but>` +- :ref:`lang-isButtonPressed` +- :ref:`lang-pinmode` +- :ref:`lang-digitalWrite` +- :ref:`lang-togglepin` + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/api/digitalwrite.rst b/docs/source/lang/api/digitalwrite.rst new file mode 100644 index 0000000..bae8db9 --- /dev/null +++ b/docs/source/lang/api/digitalwrite.rst @@ -0,0 +1,56 @@ +.. highlight:: cpp + +.. _lang-digitalwrite: + +digitalWrite() +============== + +Write a :ref:`HIGH <lang-constants-high>` or a :ref:`LOW +<lang-constants-low>` value to a pin configured as :ref:`OUTPUT +<lang-constants-output>`. + +Library Documentation +--------------------- + +.. doxygenfunction:: digitalWrite + +Discussion +---------- + +If the pin has been configured as an ``OUTPUT`` with :ref:`pinMode() +<lang-pinmode>` its voltage will be set to the corresponding value: +3.3V for ``HIGH``, and 0V (ground) for ``LOW``. + +Because it is soldered to an LED and resistor in series, your board's +:ref:`BOARD_LED_PIN <lang-board-values-led>` will respond slightly +more slowly as an output than the other pins. + +Example +------- + +The following example sets the built-in LED pin to ``HIGH``, makes a +one-second-long delay, sets the pin back to ``LOW``, and delays again, +causing a blinking pattern (you could also use +:ref:`lang-toggleled`):: + + void setup() { + pinMode(BOARD_LED_PIN, OUTPUT); // sets the digital pin as output + } + + void loop() { + digitalWrite(BOARD_LED_PIN, HIGH); // sets the LED on + delay(1000); // waits for a second + digitalWrite(BOARD_LED_PIN, LOW); // sets the LED off + delay(1000); // waits for a second + } + +See Also +-------- + +- :ref:`pinMode <lang-pinmode>` +- :ref:`digitalRead <lang-digitalread>` +- :ref:`BOARD_LED_PIN <lang-board-values-led>` +- :ref:`lang-toggleled` +- :ref:`lang-togglepin` + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/api/disabledebugports.rst b/docs/source/lang/api/disabledebugports.rst new file mode 100644 index 0000000..283cdbf --- /dev/null +++ b/docs/source/lang/api/disabledebugports.rst @@ -0,0 +1,33 @@ +.. highlight:: cpp + +.. _lang-disabledebugports: + +disableDebugPorts() +=================== + +Used to disable the JTAG and Serial Wire debugging ports. + +Library Documentation +--------------------- + +.. doxygenfunction:: disableDebugPorts + +Example +------- + + :: + + void setup() { + disableDebugPorts(); + } + + void loop() { + // Now you can use the debug port pins (the pins on the JTAG + // header on the Maple) as ordinary pins. + } + +See Also +-------- + +- :ref:`lang-enabledebugports` +- :ref:`Important erratum on Maple pin 43 <maple-nrst-pb4>` diff --git a/docs/source/lang/api/enabledebugports.rst b/docs/source/lang/api/enabledebugports.rst new file mode 100644 index 0000000..bee2b0a --- /dev/null +++ b/docs/source/lang/api/enabledebugports.rst @@ -0,0 +1,31 @@ +.. highlight:: cpp + +.. _lang-enabledebugports: + +enableDebugPorts() +================== + +Used to enable the JTAG and Serial Wire debugging ports. + +Library Documentation +--------------------- + +.. doxygenfunction:: enableDebugPorts + +Example +------- + + :: + + void setup() { + enableDebugPorts(); + // Now you can debug using JTAG and SW-Debug + } + + void loop() { + } + +See Also +-------- + +* :ref:`lang-disabledebugports` diff --git a/docs/source/lang/api/hardwarespi.rst b/docs/source/lang/api/hardwarespi.rst new file mode 100644 index 0000000..a44a65f --- /dev/null +++ b/docs/source/lang/api/hardwarespi.rst @@ -0,0 +1,170 @@ +.. highlight:: cpp + +.. _lang-hardwarespi: + +HardwareSPI +=========== + +This page describes how to use the built-in SPI ports. It does not +describe the SPI protocol itself. For more information about SPI, see +the :ref:`SPI reference <spi>`. + +.. contents:: Contents + :local: + +Getting Started +--------------- + +In order to get started, you'll first need to define a ``HardwareSPI`` +variable, which you'll use to control the SPI port. Do this by +putting the line "``HardwareSPI spi(number);``" with your variables, +where ``number`` is the SPI port's number. + +Here's an example (we'll fill in :ref:`setup() <lang-setup>` and +:ref:`loop() <lang-loop>` later):: + + // Use SPI port number 1 + HardwareSPI spi(1); + + void setup() { + // Your setup code + } + + void loop() { + // Do stuff with SPI + } + +Turning the SPI Port On +----------------------- + +Now it's time to turn your SPI port on. Do this with the ``begin()`` +function (an example is given below). + +.. FIXME [Breathe] Output doesn't include the class; fix & submit pull req + +.. doxygenfunction:: HardwareSPI::begin + +.. note:: If you are using SPI port 3 (on a board that supports it; + not all do); you'll need to call :ref:`lang-disabledebugports` + before calling ``begin()``. + +The speed at which the SPI port communicates is configured using a +``SPIFrequency`` value: + +.. FIXME [0.1.0] Breathe's enum output is enormous; shrink & submit pull req + +.. doxygenenum:: SPIFrequency + +.. note:: Due to hardware issues, you can't use the frequency + ``SPI_140_625KHz`` with SPI port 1. + +The "mode" value determines the clock phase and polarity, like so: + +.. doxygenenum:: spi_mode + +You'll need to determine the correct values for ``frequency``, +``bitOrder``, and ``mode`` yourself, by consulting the datasheet for +the device you're communicating with. Continuing our example from +before, we'll add a call to ``begin()`` to our ``setup()``:: + + // Use SPI port number 1 + HardwareSPI spi(1); + + void setup() { + // Turn on the SPI port + spi.begin(SPI_18MHZ, MSBFIRST, 0); + } + + void loop() { + // Do stuff with SPI + } + +If you call ``begin()`` with no arguments (as in "``spi.begin();``"), +it's the same as if you wrote "``spi.begin(SPI_1_125MHZ, MSBFIRST, +0);``". + +Communicating Over SPI +---------------------- + +Now that you've got your SPI port set up, it's time to start +communicating. You can send data using ``HardwareSPI::write()``, +receive data using ``HardwareSPI::read()``, and do both using +``HardwareSPI::transfer()``. + +.. cpp:function:: void HardwareSPI::write(byte data) + + Send a single byte of data. + + **Parameters**: + + - ``data``: Byte to send + +.. cpp:function:: byte HardwareSPI::read() + + Get the next available, unread byte. If there aren't any unread + bytes, this function will wait until one is received. + +.. cpp:function:: byte HardwareSPI::transfer(byte data) + + Send a byte, then return the next byte received. + + **Parameters:** + + - ``data``: Byte to send + + **Returns:** Next unread byte + +Continuing our example from before, let's send a number over SPI and +print out whatever we get back over :ref:`lang-serialusb`:: + + // Use SPI port number 1 + HardwareSPI spi(1); + + void setup() { + // Turn on the SPI port + spi.begin(SPI_18MHZ, MSBFIRST, 0); + } + + void loop() { + // Send 245 over SPI, and wait for a response. + spi.write(245); + byte response = spi.read(); + // Print out the response received. + SerialUSB.print("response: "); + SerialUSB.println(response, DEC); + } + +HardwareSPI Class Reference +--------------------------- + +There are a number of other things you can accomplish with your +``spi`` object. A full function listing follows. + +.. doxygenclass:: HardwareSPI + :members: HardwareSPI, begin, beginSlave, end, read, write, transfer + +Deprecated Functions +-------------------- + +The following functions are defined for now, but they have been +deprecated, and will be removed in a future Maple IDE release. You +shouldn't use them in new programs, and you should change any of your +programs which do use them to the up-to-date functions discussed +above. + +.. cpp:function:: uint8 HardwareSPI::send(uint8 *data, uint32 length) + + Writes ``data`` into the port buffer to be transmitted as soon as + possible, where ``length`` is the number of bytes to send from + ``data``. Returns the last byte shifted back from slave. + +.. cpp:function:: uint8 HardwareSPI::send(uint8 data) + + Writes the single byte ``data`` into the port buffer to be + transmitted as soon as possible. Returns the data byte shifted + back from the slave. + +.. cpp:function:: uint8 HardwareSPI::recv() + + Reads a byte from the peripheral. Returns the next byte in the + buffer. diff --git a/docs/source/lang/api/hardwaretimer.rst b/docs/source/lang/api/hardwaretimer.rst new file mode 100644 index 0000000..b919e52 --- /dev/null +++ b/docs/source/lang/api/hardwaretimer.rst @@ -0,0 +1,345 @@ +.. highlight:: cpp + +.. _lang-hardwaretimer: + +HardwareTimer +============= + +This page describes how to control the built-in timers. It does not +describe how the timers work on your board. For more information on +that, the :ref:`timers reference <timers>`. + +.. warning:: The timer interface is still taking shape, and is + expected to change significantly between releases. Because of + that, the functionality described in this page shouldn't be + considered stable. + + If you want a timer API that will be consistent between releases of + the Maple IDE, your best bet for now is to use the low-level + support in :ref:`libmaple-timer`. + +.. contents:: Contents + :local: + +.. _lang-hardwaretimer-getting-started: + +Getting Started +--------------- + +You'll first need to define a ``HardwareTimer`` variable, which you'll +use to control the timer. Do this by putting the line +"``HardwareTimer timer(number);``" with your variables, where +``number`` is the timer's number. + +Here's an example (we'll fill in :ref:`setup() <lang-setup>` and +:ref:`loop() <lang-loop>` later):: + + // Use timer 1 + HardwareTimer timer(1); + + void setup() { + // Your setup code + } + + void loop() { + // ... + } + +Configuring the Prescaler and Overflow +-------------------------------------- + +After defining your ``timer`` variable, you'll probably want to +configure how fast your timer's counter changes (using the prescaler) +and when it gets reset to zero (using the overflow value). You can do +that with the ``setPrescaleFactor()`` and ``setOverflow()`` functions. + +.. _lang-hardwaretimer-setprescalefactor: + +.. doxygenfunction:: HardwareTimer::setPrescaleFactor + :no-link: + +.. _lang-hardwaretimer-setoverflow: + +.. doxygenfunction:: HardwareTimer::setOverflow + :no-link: + +For example:: + + // Use timer 1 + HardwareTimer timer(1); + + void setup() { + timer.setPrescaleFactor(5); + timer.setOverflow(255); + } + + void loop() { + // ... + } + +You may also find the ``setPeriod()`` function useful: + +.. _lang-hardwaretimer-setperiod: + +.. doxygenfunction:: HardwareTimer::setPeriod + :no-link: + +For example:: + + // Use timer 1 + HardwareTimer timer(1); + + void setup() { + // Have the timer repeat every 20 milliseconds + int microseconds_per_millisecond = 1000; + timer.setPeriod(20 * microseconds_per_millisecond); + } + + void loop() { + // ... + } + +.. _lang-hardwaretimer-interrupts: + +Using Timer Interrupts +---------------------- + +.. TODO [0.2.0] Improve the interrupts section, here or in timers.rst + +In order to use timer interrupts, we recommend the following sequence: + +* Pause the timer. +* Configure the prescaler and overflow. +* Pick a timer channel to handle the interrupt and set the channel's + :ref:`mode <lang-hardwaretimer-timermode>` to ``TIMER_OUTPUT_COMPARE``. +* Set the channel compare value appropriately (this controls what counter value, + from 0 to overflow - 1). If you just want to make the interrupt fire once + every time the timer overflows, and you don't care what the timer count is, + the channel compare value can just be 1. +* Attach an interrupt handler to the channel. +* Refresh the timer. +* Resume the timer. + +Here are two complete examples. + +**LED blink**: This example blinks the built-in LED without doing +anything in ``loop()``. :: + + #define LED_RATE 500000 // in microseconds; should give 0.5Hz toggles + + // We'll use timer 2 + HardwareTimer timer(2); + + void setup() { + // Set up the LED to blink + pinMode(BOARD_LED_PIN, OUTPUT); + + // Pause the timer while we're configuring it + timer.pause(); + + // Set up period + timer.setPeriod(LED_RATE); // in microseconds + + // Set up an interrupt on channel 1 + timer.setMode(TIMER_CH1, TIMER_OUTPUT_COMPARE); + timer.setCompare(TIMER_CH1, 1); // Interrupt 1 count after each update + timer.attachInterrupt(1, handler_led); + + // Refresh the timer's count, prescale, and overflow + timer.refresh(); + + // Start the timer counting + timer.resume(); + } + + void loop() { + // Nothing! It's all in the handler_led() interrupt: + } + + void handler_led(void) { + toggleLED(); + } + +**Racing Counters**: This example shows how to use multiple timers at +the same time. :: + + int count3 = 0; + int count4 = 0; + + // We'll use timers 3 and 4 + HardwareTimer timer3(3); + HardwareTimer timer4(4); + + void setup() { + // Set up the button for input + pinMode(BOARD_BUTTON_PIN, INPUT_PULLUP); + + // Set up timers to add 1 to their counts each time + // their interrupts fire. + timer3.setMode(TIMER_CH1, TIMER_OUTPUT_COMPARE); + timer4.setMode(TIMER_CH1, TIMER_OUTPUT_COMPARE); + timer3.pause(); + timer4.pause(); + timer3.setCount(0); + timer4.setCount(0); + timer3.setOverflow(30000); + timer4.setOverflow(30000); + timer3.setCompare(TIMER_CH1, 1000); // somewhere in the middle + timer4.setCompare(TIMER_CH1, 1000); + timer3.attachCompare1Interrupt(handler3); + timer4.attachCompare1Interrupt(handler4); + timer3.refresh(); + timer4.refresh(); + timer3.resume(); + timer4.resume(); + } + + void loop() { + // Display the running counts + SerialUSB.print("Count 3: "); + SerialUSB.print(count3); + SerialUSB.print("\t\tCount 4: "); + SerialUSB.println(count4); + + // While the button is held down, pause timer 4 + for (int i = 0; i < 1000; i++) { + if (digitalRead(BOARD_BUTTON_PIN)) { + timer4.pause(); + } else { + timer4.resume(); + } + delay(1); + } + } + + void handler3(void) { + count3++; + } + + void handler4(void) { + count4++; + } + +``HardwareTimer`` Class Reference +--------------------------------- + +This section gives a full listing of the capabilities of a +``HardwareTimer``. + +.. doxygenclass:: HardwareTimer + :members: HardwareTimer, pause, resume, getPrescaleFactor, setPrescaleFactor, getOverflow, setOverflow, getCount, setCount, setPeriod, setMode, getCompare, setCompare, attachInterrupt, detachInterrupt, refresh + +.. _lang-hardwaretimer-timermode: + +.. doxygenenum:: timer_mode + +Deprecated Functionality +------------------------ + +The following functionality exists for now, but it has been +deprecated, and will be removed in a future Maple IDE release. You +shouldn't use it in new programs, and you should change any of your +programs which do use them to use the up-to-date features described +above. + +The ``TimerMode`` type from previous releases has been renamed +``timer_mode``. The mode ``TIMER_OUTPUTCOMPARE`` is still present, +but will be removed in a future release. Use ``TIMER_OUTPUT_COMPARE`` +instead. + +.. cpp:function:: void HardwareTimer::attachCompare1Interrupt(voidFuncPtr handler) + + Use ``attachInterrupt(1, handler)`` instead. + +.. cpp:function:: void HardwareTimer::attachCompare2Interrupt(voidFuncPtr handler) + + Use ``attachInterrupt(2, handler)`` instead. + +.. cpp:function:: void HardwareTimer::attachCompare3Interrupt(voidFuncPtr handler) + + Use ``attachInterrupt(3, handler)`` instead. + +.. cpp:function:: void HardwareTimer::attachCompare4Interrupt(voidFuncPtr handler) + + Use ``attachInterrupt(4, handler)`` instead. + +.. _lang-hardwaretimer-setchannelmode: + +.. cpp:function:: void HardwareTimer::setChannelMode(int channel, timer_mode mode) + + Use ``setMode(channel, mode)`` instead. + +.. cpp:function:: void HardwareTimer::setChannel1Mode(timer_mode mode) + + Use ``setMode(1, mode)`` instead. + +.. cpp:function:: void HardwareTimer::setChannel2Mode(timer_mode mode) + + Use ``setMode(2, mode)`` instead. + +.. cpp:function:: void HardwareTimer::setChannel3Mode(timer_mode mode) + + Use ``setMode(3, mode)`` instead. + +.. cpp:function:: void HardwareTimer::setChannel4Mode(timer_mode mode) + + Use ``setMode(4, mode)`` instead. + +.. cpp:function:: uint16 HardwareTimer::getCompare1() + + Use ``getCompare(1, mode)`` instead. + +.. cpp:function:: uint16 HardwareTimer::getCompare2() + + Use ``getCompare(2, mode)`` instead. + +.. cpp:function:: uint16 HardwareTimer::getCompare3() + + Use ``getCompare(3, mode)`` instead. + +.. cpp:function:: uint16 HardwareTimer::getCompare4() + + Use ``getCompare(4, mode)`` instead. + +.. cpp:function:: void HardwareTimer::setCompare1(uint16 compare) + + Use ``setCompare(1, compare)`` instead. + +.. cpp:function:: void HardwareTimer::setCompare2(uint16 compare) + + Use ``setCompare(2, compare)`` instead. + +.. cpp:function:: void HardwareTimer::setCompare3(uint16 compare) + + Use ``setCompare(3, compare)`` instead. + +.. cpp:function:: void HardwareTimer::setCompare4(uint16 compare) + + Use ``setCompare(4, compare)`` instead. + +.. cpp:function:: void HardwareTimer::detachCompare1Interrupt() + + Use ``detachInterrupt(1)`` instead. + +.. cpp:function:: void HardwareTimer::detachCompare2Interrupt() + + Use ``detachInterrupt(2)`` instead. + +.. cpp:function:: void HardwareTimer::detachCompare3Interrupt() + + Use ``detachInterrupt(3)`` instead. + +.. cpp:function:: void HardwareTimer::detachCompare4Interrupt() + + Use ``detachInterrupt(4)`` instead. + +.. cpp:function:: void HardwareTimer::generateUpdate() + + Use ``refresh()`` instead. + +In previous releases, to interact with a particular timers, you would +use one of the predefined ``HardwareTimer`` instances ``Timer1``, +``Timer2``, ``Timer3``, and ``Timer4``. These are still available for +now, but they are also deprecated, and will be removed in a future +release. As detailed in :ref:`lang-hardwaretimer-getting-started`, +you should define your own ``HardwareTimer`` variables. diff --git a/docs/source/lang/api/highbyte.rst b/docs/source/lang/api/highbyte.rst new file mode 100644 index 0000000..4cb6f9b --- /dev/null +++ b/docs/source/lang/api/highbyte.rst @@ -0,0 +1,55 @@ +.. highlight:: cpp + +.. _lang-highbyte: + +highByte() +========== + +(Macro) Extracts the second lowest byte of an integral data type. + +.. warning:: This macro is provided for compatibility with Arduino + only. It returns the second-least significant byte in an integral + value. It makes sense to call this the "high" byte on a 16-bit + ``int`` microcontroller like the Atmel chips on Arduinos, but it + makes no sense at all on a 32-bit microcontroller like the STM32s + in the Maple line. + + In short: we provide this so that existing Arduino code works as + expected, but **strongly discourage its use** in new programs. + +Syntax +------ + +:: + + highByte(x) + +Parameters +---------- + +**x**: a value of any integral type. + +Returns +------- + +Second lowest byte in **x**. + +Example +------- + +:: + + int x = 0xDEADBEEF; + SerialUSB.println(x, HEX); // prints "BE" + +Arduino Compatibility +--------------------- + +The Maple version of ``highByte()`` is compatible with Arduino. + +See Also +-------- + +- :ref:`lowByte() <lang-lowbyte>` + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/api/interrupts.rst b/docs/source/lang/api/interrupts.rst new file mode 100644 index 0000000..58fd2cc --- /dev/null +++ b/docs/source/lang/api/interrupts.rst @@ -0,0 +1,47 @@ +.. highlight:: cpp + +.. _lang-interrupts: + +interrupts() +============ + +Re-enables interrupts (after they've been disabled by +:ref:`noInterrupts() <lang-nointerrupts>`). Interrupts allow certain +important tasks to happen in the background, and certain interrupts +are enabled by default. + +Some functions will not work while interrupts are disabled, and both +incoming and outgoing communication may be ignored. Interrupts can +slightly disrupt the timing of code, however, and may be disabled for +particularly critical sections of code. + +Library Documentation +--------------------- + +.. doxygenfunction:: interrupts + +Example +------- + +:: + + void setup() {} + + void loop() { + noInterrupts(); + // critical, time-sensitive code here + interrupts(); + // other code here + } + +See Also +-------- + +- :ref:`noInterrupts() <lang-nointerrupts>` +- :ref:`attachInterrupt() <lang-attachinterrupt>` +- :ref:`detachInterrupt() <lang-detachinterrupt>` +- :ref:`Timers reference <timers>` +- :ref:`Timer API <lang-hardwaretimer>` +- :ref:`External interrupts <external-interrupts>` + +.. include:: /lang/cc-attribution.txt diff --git a/docs/source/lang/api/isbuttonpressed.rst b/docs/source/lang/api/isbuttonpressed.rst new file mode 100644 index 0000000..8c350b9 --- /dev/null +++ b/docs/source/lang/api/isbuttonpressed.rst @@ -0,0 +1,20 @@ +.. _lang-isbuttonpressed: + +isButtonPressed() +================= + +Check whether the board's built-in button (labeled BUT on the +silkscreen) is pressed. The pin number of the built-in button is +given by the constant ``BOARD_BUTTON_PIN``. + +Library Documentation +--------------------- + +.. doxygenfunction:: isButtonPressed + +See Also +-------- + +- :ref:`Board-specific values <lang-board-values>` +- :ref:`BOARD_BUTTON_PIN <lang-board-values-but>` +- :ref:`lang-waitforbuttonpress` diff --git a/docs/source/lang/api/loop.rst b/docs/source/lang/api/loop.rst new file mode 100644 index 0000000..c2a5097 --- /dev/null +++ b/docs/source/lang/api/loop.rst @@ -0,0 +1,44 @@ +.. highlight:: cpp + +.. _lang-loop: + +loop() +====== + +After creating a :ref:`setup() <lang-setup>` function, which +initializes your sketch, the ``loop()`` function gets called +repeatedly, allowing your program to change and respond. Use it to +actively control your Maple board. + +Example +------- + +:: + + int buttonPin = 38; + + // setup initializes serial and the button pin + void setup() { + SerialUSB.begin(); + pinMode(buttonPin, INPUT); + } + + // loop() checks the button pin each time it executes, + // and will print 'H' if it is pressed, 'L' otherwise + void loop() { + if (digitalRead(buttonPin) == HIGH) { + SerialUSB.println('H'); + } else { + SerialUSB.println('L'); + } + + delay(1000); + } + +See Also +-------- + +- :ref:`setup() <lang-setup>` + + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/api/lowbyte.rst b/docs/source/lang/api/lowbyte.rst new file mode 100644 index 0000000..c513711 --- /dev/null +++ b/docs/source/lang/api/lowbyte.rst @@ -0,0 +1,25 @@ +.. _lang-lowbyte: + +lowByte() +========= + +Extracts the low-order (rightmost) byte of a variable (e.g. a +word). + +Syntax +------ + +lowByte(x) + +Parameters +---------- + +**x**: a value of any type. However, if a non-integral type is used, +the results will be strange. + +Returns +------- + +The low byte's value (this will be between 0 and 255). + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/api/map.rst b/docs/source/lang/api/map.rst new file mode 100644 index 0000000..69661a0 --- /dev/null +++ b/docs/source/lang/api/map.rst @@ -0,0 +1,68 @@ +.. highlight:: cpp + +.. _lang-map: + +map() +===== + +Re-maps a number from one range to another. + +.. contents:: Contents + :local: + +Library Documentation +--------------------- + +.. doxygenfunction:: map + +Discussion +---------- + +``map()`` does not constrain values to within the range, because +out-of-range values are sometimes intended and useful. The +:ref:`constrain() <lang-constrain>` macro may be used either before or +after this function, if limits to the ranges are desired. + +Note that the "lower bounds" of either range may be larger or smaller +than the "upper bounds" so that ``map()`` may be used to reverse a +range of numbers; for example:: + + y = map(x, 1, 50, 50, 1); + +The function also handles negative numbers well, so that this +example :: + + y = map(x, 1, 50, 50, -100); + +is also valid. + +The ``map()`` function uses integer math (its arguments and return +values all have type :ref:`long <lang-long>`), so it will not generate +fractions, when the math might indicate that it should do so. +Fractional remainders are truncated, and are not rounded or averaged. + +Example +------- + +:: + + /* Map an ADC reading (12 bits) to 16-bit PWM (0 to 65,535) */ + + void setup() { + pinMode(0, INPUT_ANALOG); + pinMode(9, PWM); + } + + void loop() { + int val = analogRead(0); + val = map(val, 0, 4095, 0, 65535); + analogWrite(9, val); + } + + +See Also +-------- + +- :ref:`constrain() <lang-constrain>` + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/api/max.rst b/docs/source/lang/api/max.rst new file mode 100644 index 0000000..d356f08 --- /dev/null +++ b/docs/source/lang/api/max.rst @@ -0,0 +1,64 @@ +.. highlight:: cpp + +.. _lang-max: + +max() +===== + +(Macro) Calculates the maximum of two numbers. + +Syntax +------ + +:: + + max(x, y) + +Parameters +---------- + +**x**: the first number; may be any number or numeric expression. + +**y**: the second number; may be any number or numeric expression. + + +Returns +------- + +The larger of the two parameter values. + +Example +------- + +:: + + sensVal = max(senVal, 20); // assigns sensVal to the larger of sensVal or 20 + // (effectively ensuring that it is at least 20) + +.. note:: Perhaps counter-intuitively, max() is often used to + constrain the lower end of a variable's range, while :ref:`min() + <lang-min>` is used to constrain the upper end of the range. + +Warning +------- + +Because of the way ``max()`` is implemented, avoid using other +functions inside the parentheses. It may lead to incorrect results:: + + max(a--, 0); // avoid this - yields incorrect results + + a--; // use this instead - + max(a, 0); // keep other operations outside max() + +Arduino Compatibility +--------------------- + +The Maple implementation of ``max()`` is compatible with Arduino. + +See Also +-------- + +- :ref:`min() <lang-min>` +- :ref:`constrain() <lang-constrain>` + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/api/micros.rst b/docs/source/lang/api/micros.rst new file mode 100644 index 0000000..de85303 --- /dev/null +++ b/docs/source/lang/api/micros.rst @@ -0,0 +1,46 @@ +.. highlight:: cpp + +.. _lang-micros: + +micros() +======== + +Returns the number of microseconds since the Maple board began running +the current program. This number will overflow (go back to zero), +after approximately 70 minutes. + +.. note:: There are 1,000 microseconds in a millisecond, and 1,000,000 + microseconds in a second. + +Library Documentation +--------------------- + +.. doxygenfunction:: micros + +Example +------- + +:: + + unsigned int time; + + void setup() { + } + + void loop() { + SerialUSB.print("Time: "); + time = micros(); + // prints time since program started + SerialUSB.println(time); + // wait a second so as not to send massive amounts of data + delay(1000); + } + +See Also +-------- + +- :ref:`millis() <lang-millis>` +- :ref:`delay() <lang-delay>` +- :ref:`delayMicroseconds() <lang-delaymicroseconds>` + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/api/millis.rst b/docs/source/lang/api/millis.rst new file mode 100644 index 0000000..b6fbf55 --- /dev/null +++ b/docs/source/lang/api/millis.rst @@ -0,0 +1,52 @@ +.. highlight:: cpp + +.. _lang-millis: + +millis() +======== + +Returns the number of milliseconds since the Maple board began running +the current program. This number will overflow (go back to zero) after +approximately 50 days. + +Library Documentation +--------------------- + +.. doxygenfunction:: millis + +Example +------- + +The following time prints the value returned by ``millis()`` roughly +once per second:: + + unsigned int time; + + void setup() { + } + + void loop() { + SerialUSB.print("Time: "); + time = millis(); + // prints time since program started + SerialUSB.println(time); + + // wait a second so as not to send massive amounts of data + delay(1000); + } + +Tip +--- + +Since the return value for ``millis()`` is an :ref:`unsigned long +<lang-unsignedlong>`, overflow errors may occur if you try to do math +with other data types, such as :ref:`chars <lang-char>`. + +See Also +-------- + +- :ref:`micros <lang-micros>` +- :ref:`delay <lang-delay>` +- :ref:`delayMicroseconds <lang-delaymicroseconds>` + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/api/min.rst b/docs/source/lang/api/min.rst new file mode 100644 index 0000000..3307105 --- /dev/null +++ b/docs/source/lang/api/min.rst @@ -0,0 +1,65 @@ +.. highlight:: cpp + +.. _lang-min: + +min() +===== + +(Macro) Calculates the minimum of two numbers. + +Syntax +------ + +:: + + min(x,y) + +Parameters +---------- + +**x**: the first number; may be any number or numeric expression. + +**y**: the second number; may be any number or numeric expression. + +Returns +------- + +The smaller of the two numbers. + +Example +------- + +:: + + sensVal = min(sensVal, 100); // assigns sensVal to the smaller of sensVal or 100 + // ensuring that it never gets above 100. + + +.. note:: Perhaps counter-intuitively, max() is often used to + constrain the lower end of a variable's range, while min() is used + to constrain the upper end of the range. + + +Warning +------- + +Because of the way ``min()`` is implemented, avoid using other +functions inside the parentheses. It may lead to incorrect results:: + + min(a++, 100); // avoid this - yields incorrect results + + a++; // use this instead - + min(a, 100); // keep other operations outside min() + +Arduino Compatibility +--------------------- + +The Maple version of ``min()`` is compatible with Arduino. + +See Also +-------- + +- :ref:`max() <lang-max>` +- :ref:`constrain() <lang-constrain>` + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/api/nointerrupts.rst b/docs/source/lang/api/nointerrupts.rst new file mode 100644 index 0000000..68f0498 --- /dev/null +++ b/docs/source/lang/api/nointerrupts.rst @@ -0,0 +1,47 @@ +.. highlight:: cpp + +.. _lang-nointerrupts: + +noInterrupts() +============== + +Description +----------- + +Disables interrupts. Interrupts allow certain important tasks to +happen in the background and are enabled by default. Some functions +will not work while interrupts are disabled, and incoming +communication may be ignored. Interrupts can slightly disrupt the +timing of code, however, and may be disabled for particularly critical +sections of code. + +Library Documentation +--------------------- + +.. doxygenfunction:: noInterrupts + +Example +------- + +:: + + void setup() {} + + void loop() { + noInterrupts(); + // critical, time-sensitive code here + interrupts(); + // other code here + } + +See Also +-------- + +- :ref:`interrupts() <lang-interrupts>` +- :ref:`attachInterrupt() <lang-attachinterrupt>` +- :ref:`detachInterrupt() <lang-detachinterrupt>` +- :ref:`Timers reference <timers>` +- :ref:`Timer API <lang-hardwaretimer>` +- :ref:`External interrupts <external-interrupts>` + +.. include:: /lang/cc-attribution.txt diff --git a/docs/source/lang/api/pinmode.rst b/docs/source/lang/api/pinmode.rst new file mode 100644 index 0000000..643e26e --- /dev/null +++ b/docs/source/lang/api/pinmode.rst @@ -0,0 +1,80 @@ +.. highlight:: cpp + +.. _lang-pinmode: + +pinMode() +========= + +.. contents:: Contents + :local: + +Library Documentation +--------------------- + +.. doxygenfunction:: pinMode + +.. _lang-pinmode-wiringpinmode: + +.. doxygenenum:: WiringPinMode + +Discussion +---------- + +pinMode() is usually called within :ref:`lang-setup` in order to +configure a pin for a certain usage (although it may be called +anywhere). + +Example +------- + +This example uses pinMode() to set up the pin connected to the +built-in LED as an output. Once this is done, +:ref:`lang-digitalwrite` can be used to turn the pin ``HIGH`` and +``LOW``, which turn the LED on and off. + +:: + + void setup() { + pinMode(BOARD_LED_PIN, OUTPUT); // sets the LED pin as output + } + + void loop() { + digitalWrite(BOARD_LED_PIN, HIGH); // sets the LED on + delay(1000); // waits for a second + digitalWrite(BOARD_LED_PIN, LOW); // sets the LED off + delay(1000); // waits for a second + } + +Arduino Compatibility +--------------------- + +.. TODO check out Arduino vs. Maple static discilpline cutoffs to +.. ensure accuracy of following: + +On Maple, pinMode() supports the ``INPUT`` and ``OUTPUT`` modes in the +same way as Arduino (however, remember that the Maple, as a 3.3V +device, will only drive 3.3V to an ``OUTPUT`` pin that has been set +``HIGH``, instead of 5V like on Arduino). + +``INPUT_ANALOG`` and ``PWM`` modes were added because the Maple +doesn't separate the analog and digital pins the same way Arduino +does. Unlike on Arduino, you **must call** pinMode() to set up a pin +for these purposes before a call to, e.g., :ref:`lang-analogRead`. +This should only add a few lines to your :ref:`lang-setup` function. + +.. TODO [0.1.0] verify following before putting it in: + +.. ``OUTPUT_OPEN_DRAIN``, ``INPUT_PULLUP``, ``INPUT_PULLDOWN``, and +.. ``PWM_OPEN_DRAIN`` modes represent functionality not currently +.. available on Arduino boards. + +See Also +-------- + +- :ref:`lang-board-values` +- :ref:`lang-constants` +- :ref:`lang-digitalwrite` +- :ref:`lang-digitalread` +- :ref:`gpio` + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/api/pow.rst b/docs/source/lang/api/pow.rst new file mode 100644 index 0000000..219a866 --- /dev/null +++ b/docs/source/lang/api/pow.rst @@ -0,0 +1,20 @@ +.. _lang-pow: + +pow() +===== + +Calculates the value of a number raised to a power. + +Library Documentation +--------------------- + +.. doxygenfunction:: pow + +See Also +-------- + +- :ref:`sqrt() <lang-sqrt>` +- :ref:`float <lang-float>` +- :ref:`double <lang-double>` + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/api/pwmwrite.rst b/docs/source/lang/api/pwmwrite.rst new file mode 100644 index 0000000..5cc112e --- /dev/null +++ b/docs/source/lang/api/pwmwrite.rst @@ -0,0 +1,61 @@ +.. highlight:: cpp + +.. _lang-pwmwrite: + +pwmWrite() +========== + +Writes a :ref:`PWM wave <pwm>` to a pin. You can use this to make an +LED get brighter or dimmer, control a servomotor, etc. After a call to +pwmWrite(), the pin will output a steady square wave with the given +duty cycle. You can change the duty cycle later by calling pwmWrite() +again with the same pin and a different duty. + +The pins which support PWM have ``PWM`` listed underneath their number +on your board's silkscreen. These pin numbers are available to your +program in the :ref:`boardPWMPins <lang-board-values-pwm-pins>` +board-specific array. The number of pins which are capable of PWM on +your board is given by the ``BOARD_NR_PWM_PINS`` constant. These +values are documented for each board in the :ref:`Board Hardware +Documentation <index-boards>` pages. + +The Arduino function :ref:`analogWrite() <lang-analogwrite>` is an +alias for ``pwmWrite()``, but it is badly named, and its use is +discouraged. + +.. contents:: Contents + :local: + +Library Documentation +--------------------- + +.. doxygenfunction:: pwmWrite + +Example +------- + +Sets the output to the LED proportional to the value read from the +potentiometer:: + + int analogPin = 3; // potentiometer connected to analog pin 3 + + void setup() { + pinMode(BOARD_LED_PIN, OUTPUT); // sets the LED pin as output + + pinMode(analogPin, INPUT_ANALOG); // sets the potentiometer pin as + // analog input + } + + void loop() { + int val = analogRead(analogPin); // read the input pin + + pwmWrite(BOARD_LED_PIN, val * 16); // analogRead values go from 0 + // to 4095, pwmWrite values + // from 0 to 65535, so scale roughly + } + +See Also +-------- + +- :ref:`Maple PWM tutorial <pwm>` +- :ref:`boardPWMPins <lang-board-values-pwm-pins>` diff --git a/docs/source/lang/api/random.rst b/docs/source/lang/api/random.rst new file mode 100644 index 0000000..9875ee6 --- /dev/null +++ b/docs/source/lang/api/random.rst @@ -0,0 +1,71 @@ +.. highlight:: cpp + +.. _lang-random: + +random() +======== + +The ``random()`` function generates pseudo-random numbers. + +Library Documentation +--------------------- + +.. FIXME [Breathe] use doxygenfunction when possible + +.. cpp:function:: random(long max) + + Same as a call to ``random(0, max)``. + +.. cpp:function:: random(long min, long max) + + Generate a pseudo-random number with given lower and upper bounds. + + *Parameters* + + - ``min`` - Lower bound on the returned value, inclusive + - ``max`` - Upper bound on the returned value, exclusive + + *Returns*: A pseudo-random number in the range [min, max). + +Discussion +---------- + +If it is important for a sequence of values generated by +:ref:`random() <lang-random>` to differ, on subsequent executions of a +sketch, use :ref:`randomSeed() <lang-randomseed>` to initialize the +random number generator with a fairly random input, such as +:ref:`analogRead() <lang-analogread>` on an unconnected pin. + +Conversely, it can occasionally be useful to use pseudorandom +sequences that repeat exactly. This can be accomplished by calling +``randomSeed()`` with a fixed number, before starting the random +sequence. + +Example +------- + +The following sketch initializes the random seed based on an :ref:`ADC +<adc>` reading of pin 0. If this pin is unconnected, the Sketch +should print different values to the :ref:`serial monitor +<ide-serial-monitor>` each time it is run:: + + long randNumber; + + void setup() { + pinMode(0, INPUT_ANALOG); + randomSeed(analogRead(0)); + } + + void loop() { + randNumber = random(300); + SerialUSB.println(randNumber); + + delay(50); + } + +See Also +-------- + +- :ref:`randomSeed() <lang-randomseed>` + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/api/randomseed.rst b/docs/source/lang/api/randomseed.rst new file mode 100644 index 0000000..ca7b75f --- /dev/null +++ b/docs/source/lang/api/randomseed.rst @@ -0,0 +1,60 @@ +.. highlight:: cpp + +.. _lang-randomseed: + +randomSeed() +============ + +``randomSeed()`` initializes the `pseudorandom number generator +<http://en.wikipedia.org/wiki/Pseudorandom_number_generator>`_, +causing it to start at an arbitrary point in its random sequence. +This sequence, while very long, and random, is always the same. + + +Library Documentation +--------------------- + +.. doxygenfunction:: randomSeed + +Discussion +---------- + +If it is important for a sequence of values generated by +:ref:`random() <lang-random>` to differ, on subsequent executions of a +sketch, use ``randomSeed()`` to initialize the random number generator +with a fairly random input, such as :ref:`analogRead() +<lang-analogread>` on an unconnected pin. + +Conversely, it can occasionally be useful to use pseudorandom +sequences that repeat exactly. This can be accomplished by calling +``randomSeed()`` with a fixed number, before starting the random +sequence. + +Example +------- + +The following sketch initializes the random seed based on an :ref:`ADC +<adc>` reading of pin 0. If this pin is unconnected, the Sketch +should print different values to the :ref:`serial monitor +<ide-serial-monitor>` each time it is run:: + + long randNumber; + + void setup() { + pinMode(0, INPUT_ANALOG); + randomSeed(analogRead(0)); + } + + void loop() { + randNumber = random(300); + SerialUSB.println(randNumber); + + delay(50); + } + +See Also +-------- + +- :ref:`random() <lang-random>` + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/api/serial.rst b/docs/source/lang/api/serial.rst new file mode 100644 index 0000000..e287015 --- /dev/null +++ b/docs/source/lang/api/serial.rst @@ -0,0 +1,282 @@ +.. FIXME [0.0.13] This doesn't include UART4/5, or USART6 +.. highlight:: cpp + +.. _lang-serial: + +Serial Ports (``Serial1``, ``Serial2``, ``Serial3``) +==================================================== + +This page describes how to use the built-in serial ports (also known +as USARTs). For more information about serial ports, see +:ref:`usart`. + +.. contents:: Contents + :local: + +Getting Started +--------------- + +First, decide which serial port you wish to use, and :ref:`connect its +pins to the device you're communicating with <usart-circuit>`. (The TX +and RX pins for a serial port are labeled on your board's silkscreen; +for example, serial port 2 has pins labeled "TX2" and "RX2"). + +The variable for controlling a serial port is the word ``Serial``, +plus the serial port's number. For example, you can control serial +port 1 with the variable ``Serial1``, serial port 2 with ``Serial2``, +and so on. + +In order to get started using your serial port, you'll first need to +turn it on. Do this by calling your serial port's ``begin()`` +function, giving it the baud rate you wish it to communicate at. If +you're not sure what baud rate to use, 9600 is a safe (although slow) +value to try. Put this call to ``begin()`` in your :ref:`lang-setup`, +like in the following example:: + + void setup() { + // 9600 is the baud rate to use. The baud rate determines how + // fast the communication goes. + Serial2.begin(9600); + } + + void loop() { + // Communicate using Serial2 here + } + +Communicating Over Serial +------------------------- + +Now that your serial port is set up, it's time to start communicating. + +One common use for serial ports is to print strings and other +debugging information to a computer. You can print numbers or strings +using ``print()`` and ``println()``, like this:: + + void printSomeInformation() { + Serial2.print("First, print this string. Then print a number: "); + Serial2.print(42); + Serial2.print(". You can print floating point values, too: "); + Serial2.print(3.14); + Serial2.println(". Using println() instead of print() ends the line."); + Serial2.println("This sentence starts on a new line."); + } + +This sort of communication can go both ways: you can send characters +from a computer to a serial port as well. You can check how many +characters are waiting for you to read using the ``available()`` +function, and read them out one at a time using ``read()``. The +following example program uses these functions to "echo" back anything +sent to ``Serial2``:: + + void setup() { + Serial2.begin(9600); + } + + void echoCharacter() { + // Check to see if we have received any information. numUnread + // will hold the number of bytes we've received, but haven't + // looked at yet. + int numUnread = Serial2.available(); + + // numUnread > 0 means that there are some unread bytes waiting + if (numUnread > 0) { + // Read a single byte out: + byte b = Serial2.read(); + // And then print it back: + Serial2.print(b); + } + } + + void loop() { + echoCharacter(); + } + +Function Reference +------------------ + +This section gives a full listing of functions available for use with +serial ports. + +Library Documentation +--------------------- + +All of the ``Serial[1,2,3]`` objects are instances of the +``HardwareSerial`` class, which is documented in this section. (This +means that you can use any of these functions on any of ``Serial1``, +``Serial2``, and ``Serial3``). + +.. cpp:class:: HardwareSerial + + Serial port class. Predefined instances are ``Serial1``, + ``Serial2``, and ``Serial3``. + +.. cpp:function:: void HardwareSerial::begin(unsigned int baud) + + Set up a ``HardwareSerial`` object for communications. This method + must be called before attempting to use the ``HardwareSerial`` + object (typically, you call this in your :ref:`setup() + <lang-setup>` function). + +.. cpp:function:: void HardwareSerial::end() + + Disables the USART associated with this object, allowing any + associated communication pins to be used for other purposes. + +.. cpp:function:: unsigned int HardwareSerial::available() + + Returns the number of bytes available for reading. + +.. cpp:function:: unsigned char HardwareSerial::read() + + Returns the next available, unread character. If there are no + available characters (you can check this with :cpp:func:`available + <HardwareSerial::available>`), the call will block until one + becomes available. + +.. cpp:function:: void HardwareSerial::flush() + + Throw away the contents of the serial port's receiver (RX) buffer. + That is, clears any buffered characters, so that the next character + read is guaranteed to be new. + +.. cpp:function:: void HardwareSerial::print(unsigned char b) + + Print the given byte over the USART. + +.. cpp:function:: void HardwareSerial::print(char c) + + Print the given character over the USART. 7-bit clean characters + are typically interpreted as ASCII text. + +.. cpp:function:: void HardwareSerial::print(const char *str) + + Print the given null-terminated string over the USART. + +.. cpp:function:: void HardwareSerial::print(int n) + + Print the argument's digits over the USART, in decimal format. + Negative values will be prefixed with a ``'-'`` character. + +.. cpp:function:: void HardwareSerial::print(unsigned int n) + + Print the argument's digits over the USART, in decimal format. + +.. cpp:function:: void HardwareSerial::print(long n) + + Print the argument's digits over the USART, in decimal format. + Negative values will be prefixed with a ``'-'`` character. + +.. cpp:function:: void HardwareSerial::print(unsigned long n) + + Print the argument's digits over the USART, in decimal format. + +.. cpp:function:: void HardwareSerial::print(long n, int base) + + Print the digits of ``n`` over the USART, in base ``base`` (which + may be between 2 and 16). The ``base`` value 2 corresponds to + binary, 8 to octal, 10 to decimal, and 16 to hexadecimal. Negative + values will be prefixed with a ``'-'`` character. + +.. cpp:function:: void HardwareSerial::print(double n) + + Print ``n``, accurate to 2 digits after the decimal point. + +.. _lang-serial-println: + +.. cpp:function:: void HardwareSerial::println(char c) + + Like ``print(c)``, followed by ``"\r\n"``. + +.. cpp:function:: void HardwareSerial::println(const char *c) + + Like ``print(c)``, followed by ``"\r\n"``. + +.. cpp:function:: void HardwareSerial::println(unsigned char b) + + Like ``print(b)``, followed by ``"\r\n"``. + +.. cpp:function:: void HardwareSerial::println(int n) + + Like ``print(n)``, followed by ``"\r\n"``. + +.. cpp:function:: void HardwareSerial::println(unsigned int n) + + Like ``print(n)``, followed by ``"\r\n"``. + +.. cpp:function:: void HardwareSerial::println(long n) + + Like ``print(n)``, followed by ``"\r\n"``. + +.. cpp:function:: void HardwareSerial::println(unsigned long n) + + Like ``print(n)``, followed by ``"\r\n"``. + +.. cpp:function:: void HardwareSerial::println(long n, int base) + + Like ``print(n, b)``, followed by ``"\r\n"``. + +.. cpp:function:: void HardwareSerial::println(double n) + + Like ``print(n)``, followed by ``"\r\n"``. + +.. cpp:function:: void HardwareSerial::println() + + Prints ``"\r\n"`` over the USART. + +.. cpp:function:: void HardwareSerial::write(unsigned char ch) + + Sends one character over the USART. This function is currently + blocking. + + This is a low-level function. One of the ``print()`` or + ``println()`` functions is likely to be more useful when printing + multiple characters, when formatting numbers for printing, etc. + +.. cpp:function:: void HardwareSerial::write(const char* str) + + Send the given null-terminated character string over the USART. + + This is a low-level function. One of the ``print()`` or + ``println()`` functions is likely to be more useful when printing + multiple characters, when formatting numbers for printing, etc. + +.. cpp:function:: void HardwareSerial::write(void *buf, unsigned int size) + + Writes the first ``size`` bytes of ``buf`` over the USART. Each + byte is transmitted as an individual character. + + This is a low-level function. One of the ``print()`` or + ``println()`` functions is likely to be more useful when printing + multiple characters, when formatting numbers for printing, etc. + +.. cpp:function:: int HardwareSerial::txPin() + + Return the number of the TX (transmit) pin. + +.. cpp:function:: int HardwareSerial::rxPin() + + Return the number of the RX (receive) pin. + +Arduino Compatibility Note +-------------------------- + +Unlike the Arduino, none of the Maple's serial ports is connected to +the USB port on the Maple board. If you want to communicate using the +built-in USB port, use :ref:`SerialUSB <lang-serialusb>` instead. You +will need an additional USB-to-serial adapter to communicate between a +USART and your computer. + +.. FIXME [0.1.0] port these examples over + +.. Examples +.. -------- + +.. - `ASCII Table <http://arduino.cc/en/Tutorial/ASCIITable>`_ +.. - `Dimmer <http://arduino.cc/en/Tutorial/Dimmer>`_ +.. - `Graph <http://arduino.cc/en/Tutorial/Graph>`_ +.. - `Physical Pixel <http://arduino.cc/en/Tutorial/PhysicalPixel>`_ +.. - `Virtual Color Mixer <http://arduino.cc/en/Tutorial/VirtualColorMixer>`_ +.. - `Serial Call Response <http://arduino.cc/en/Tutorial/SerialCallResponse>`_ +.. - `Serial Call Response ASCII <http://arduino.cc/en/Tutorial/SerialCallResponseASCII>`_ + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/api/serialusb.rst b/docs/source/lang/api/serialusb.rst new file mode 100644 index 0000000..ed466f2 --- /dev/null +++ b/docs/source/lang/api/serialusb.rst @@ -0,0 +1,242 @@ +.. highlight:: cpp + +.. _lang-serialusb: + +``SerialUSB`` +============= + +Used for communication between the Maple board and a computer. + +.. contents:: Contents + :local: + +Introduction +------------ + +In addition to three :ref:`serial ports <lang-serial>`, the Maple's +STM32 microprocessor includes a dedicated USB peripheral. This +peripheral is used to emulate a regular serial port for use as a +terminal. The emulated terminal is relatively slow; it is best for +transferring data at regular serial speeds (kilobaud). + +Library access to the emulated serial port is provided through the +``SerialUSB`` object. You can mostly use ``SerialUSB`` as a drop-in +replacement for ``Serial1``, ``Serial2``, and ``Serial3``. + +.. warning:: The ``SerialUSB`` functionality includes a 50 millisecond + timeout for writes, and does not try to detect if the USB host is + "really" connected, or just enumerated and initialized. + + This means that if you have a number of calls to one of the + ``SerialUSB`` ``write()`` or ``print()`` functions in your code, + and you are not monitoring ``SerialUSB`` on a computer, your + program will run much slower than if it is being monitored or + totally disconnected (run off of a battery). + + You can avoid this behavior by :ref:`deciphering the port status + using the DTR and RTS line status <lang-serialusb-safe-print>` (the + behavior of these control lines is platform dependent and we no + longer interpret them by default). + +Library Documentation +--------------------- + +The ``SerialUSB`` object is an instance of the ``USBSerial`` class, +which is documented in this section. This means that you can use any +of these functions by writing +``SerialUSB.functionName(arguments...)``. For example, to print the +message "hello, world!", you can write ``USBSerial.println("hello, +world!")``. + +.. cpp:class:: USBSerial + + Emulated serial-over-USB class. ``SerialUSB`` is the predefined + (singleton) instance. + +.. _lang-serialusb-begin: + +.. cpp:function:: USBSerial::begin() + + Set up the USB peripheral for emulated serial communication. The + peripheral is configured this way by default; calling this function + should only be necessary if you have disabled the peripheral using + ``SerialUSB.end()``. + +.. _lang-serialusb-end: + +.. cpp:function:: USBSerial::end() + + Disables the USB peripheral. Note that using this function will + terminate all USB communications between the Maple and the USB + host; in particular, it implies that you won't be able to upload + any new programs without resetting the board or using + :ref:`perpetual bootloader mode + <troubleshooting-perpetual-bootloader>`. + +.. cpp:function:: unsigned int USBSerial::available() + + Returns the number of bytes available for reading. + +.. _lang-serialusb-read: + +.. cpp:function:: unsigned char USBSerial::read() + + Returns the next available, unread character. If there are no + available characters (you can check this with :cpp:func:`available + <USBSerial::available>`), the call will block until one + becomes available. + +.. cpp:function:: USBSerial::print(unsigned char b) + + Print the given byte over the USB connection. + +.. cpp:function:: USBSerial::print(char c) + + Print the given character over the USB connection. 7-bit clean characters + are typically interpreted as ASCII text. + +.. cpp:function:: USBSerial::print(const char *str) + + Print the given null-terminated string over the USB connection. + +.. cpp:function:: USBSerial::print(int n) + + Print the argument's digits over the USB connection, in decimal format. + Negative values will be prefixed with a ``'-'`` character. + +.. cpp:function:: USBSerial::print(unsigned int n) + + Print the argument's digits over the USB connection, in decimal format. + +.. cpp:function:: USBSerial::print(long n) + + Print the argument's digits over the USB connection, in decimal + format. Negative values will be prefixed with a ``'-'`` character. + +.. cpp:function:: USBSerial::print(unsigned long n) + + Print the argument's digits over the USB connection, in decimal + format. + +.. cpp:function:: USBSerial::print(long n, int base) + + Print the digits of ``n`` over the USB connection, in base ``base`` + (which may be between 2 and 16). The ``base`` value 2 corresponds + to binary, 8 to octal, 10 to decimal, and 16 to hexadecimal. + Negative values will be prefixed with a ``'-'`` character. + +.. cpp:function:: USBSerial::print(double n) + + Print ``n``, accurate to 2 digits after the decimal point. + +.. _lang-serialusb-println: + +.. cpp:function:: USBSerial::println(char c) + + Like ``print(c)``, followed by ``"\r\n"``. + +.. cpp:function:: USBSerial::println(const char *c) + + Like ``print(c)``, followed by ``"\r\n"``. + +.. cpp:function:: USBSerial::println(unsigned char b) + + Like ``print(b)``, followed by ``"\r\n"``. + +.. cpp:function:: USBSerial::println(int n) + + Like ``print(n)``, followed by ``"\r\n"``. + +.. cpp:function:: USBSerial::println(unsigned int n) + + Like ``print(n)``, followed by ``"\r\n"``. + +.. cpp:function:: USBSerial::println(long n) + + Like ``print(n)``, followed by ``"\r\n"``. + +.. cpp:function:: USBSerial::println(unsigned long n) + + Like ``print(n)``, followed by ``"\r\n"``. + +.. cpp:function:: USBSerial::println(long n, int base) + + Like ``print(n, b)``, followed by ``"\r\n"``. + +.. cpp:function:: USBSerial::println(double n) + + Like ``print(n)``, followed by ``"\r\n"``. + +.. cpp:function:: USBSerial::println() + + Prints ``"\r\n"`` over the USB connection. + +.. cpp:function:: USBSerial::write(unsigned char ch) + + Sends one character over the USB connection. This function is + currently blocking, although nonblocking writes are a planned + future extension. + + This is a low-level function. One of the ``print()`` or + ``println()`` functions is likely to be more useful when printing + multiple characters, when formatting numbers for printing, etc. + +.. cpp:function:: USBSerial::write(const char* str) + + Send the given null-terminated character string over the USB + connection. + + This is a low-level function. One of the ``print()`` or + ``println()`` functions is likely to be more useful when printing + multiple characters, when formatting numbers for printing, etc. + +.. cpp:function:: USBSerial::write(void *buf, unsigned int size) + + Writes the first ``size`` bytes of ``buf`` over the USB connection. + Each byte is transmitted as an individual character. + + This is a low-level function. One of the ``print()`` or + ``println()`` functions is likely to be more useful when printing + multiple characters, when formatting numbers for printing, etc. + +Examples +-------- + +.. _lang-serialusb-safe-print: + +**Safe print**: This function should run smoothly and not block; the +LED should blink at roughly the same speed whether being monitored, +running from battery, or connected but not monitored. You may need to +experiment with the DTR/RTS logic for your platform and device +configuration. :: + + #define LED_PIN BOARD_LED_PIN + + void setup() { + /* Set up the LED to blink */ + pinMode(LED_PIN, OUTPUT); + } + + void loop() { + // LED will stay off if we are disconnected, and will blink + // quickly if USB is unplugged (battery power, etc.). + if(SerialUSB.isConnected()) { + digitalWrite(LED_PIN, 1); + } + delay(100); + + // If this logic fails to detect if bytes are going to be read + // by the USB host, then the println() take a long time, + // causing a very slow LED blink. If the characters are + // printed and read, the blink will only slow a small amount + // when "really" connected, and will be fast fast when the + // virtual port is only configured. + if(SerialUSB.isConnected() && (SerialUSB.getDTR() || SerialUSB.getRTS())) { + for(int i = 0; i < 10; i++) { + SerialUSB.println(123456, BIN); + } + } + digitalWrite(LED_PIN, 0); + delay(100); + } + diff --git a/docs/source/lang/api/setup.rst b/docs/source/lang/api/setup.rst new file mode 100644 index 0000000..1e8e3b8 --- /dev/null +++ b/docs/source/lang/api/setup.rst @@ -0,0 +1,29 @@ +.. highlight:: cpp + +.. _lang-setup: + +setup() +======= + +The ``setup()`` function is called when a sketch starts. Use it to +initialize :ref:`variables <lang-variables>`, :ref:`pin modes +<lang-pinmode>`, start using :ref:`libraries <libraries>`, etc. The +``setup()`` function will only run once, after each power-up or reset +of the Maple board. + +Example +------- + +:: + + int buttonPin = 38; + + void setup() { + pinMode(buttonPin, INPUT); + } + + void loop() { + // ... + } + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/api/shiftout.rst b/docs/source/lang/api/shiftout.rst new file mode 100644 index 0000000..1d9ba12 --- /dev/null +++ b/docs/source/lang/api/shiftout.rst @@ -0,0 +1,99 @@ +.. highlight:: cpp + +.. _lang-shiftout: + +shiftOut() +========== + +Shift out a byte of data, one bit at a time. + +.. contents:: Contents + :local: + +Library Documentation +--------------------- + +.. doxygenfunction:: shiftOut + +Discussion +---------- + +This is a software implementation. There is also a hardware :ref:`SPI +<spi>` library available which will be faster and consume less CPU +cycles than this function. + +Note that the ``dataPin`` and ``clockPin`` must already be configured +to :ref:`OUTPUT <lang-constants-output>` mode by a call to +:ref:`pinMode() <lang-pinmode>`. + +Also note that since shiftOut() outputs 1 byte (8 bits) at a time, it +requires multiple steps to output values larger than 255. + +Examples +-------- + +To use these examples, replace ``dataPin`` and ``clockPin`` with the +numbers of the pins you want to use:: + + /* MSBFIRST example */ + + uint16 data = 500; + // shift out high byte + shiftOut(dataPin, clockPin, MSBFIRST, (data >> 8)); + // shift out low byte + shiftOut(dataPin, clockPin, MSBFIRST, data); + + /* LSBFIRST serial */ + + data = 500; + // shift out low byte + shiftOut(dataPin, clockPin, LSBFIRST, data); + // shift out high byte + shiftOut(dataPin, clockPin, LSBFIRST, (data >> 8)); + +Arduino Tutorial Example +------------------------ + +This Arduino example runs unmodified on the Maple. For accompanying +circuit, see the `tutorial on controlling a 74HC595 shift register +<http://arduino.cc/en/Tutorial/ShiftOut>`_. + +:: + + //**************************************************************// + // Name : shiftOutCode, Hello World // + // Author : Carlyn Maw, Tom Igoe // + // Date : 25 Oct, 2006 // + // Version : 1.0 // + // Notes : Code for using a 74HC595 Shift Register // + // : to count from 0 to 255 // + //**************************************************************// + + // Pin connected to ST_CP of 74HC595 + int latchPin = 8; + // Pin connected to SH_CP of 74HC595 + int clockPin = 12; + // Pin connected to DS of 74HC595 + int dataPin = 11; + + void setup() { + // Set pins to output because they are addressed in the main loop + pinMode(latchPin, OUTPUT); + pinMode(clockPin, OUTPUT); + pinMode(dataPin, OUTPUT); + } + + void loop() { + // Count up routine + for (int j = 0; j < 256; j++) { + // Ground latchPin and hold low for as long as you are transmitting + digitalWrite(latchPin, LOW); + shiftOut(dataPin, clockPin, LSBFIRST, j); + // Return the latch pin high to signal chip that it + // no longer needs to listen for information + digitalWrite(latchPin, HIGH); + delay(1000); + } + } + +.. include:: /lang/cc-attribution.txt diff --git a/docs/source/lang/api/sin.rst b/docs/source/lang/api/sin.rst new file mode 100644 index 0000000..3e28c0b --- /dev/null +++ b/docs/source/lang/api/sin.rst @@ -0,0 +1,31 @@ +.. _lang-sin: + +sin() +===== + +Calculates the `sine <http://en.wikipedia.org/wiki/Sine>`_ of an +angle. + +Library Documentation +--------------------- + +.. doxygenfunction:: sin + +Arduino Compatibility +--------------------- + +The Maple version of ``sin()`` is compatible with Arduino. + +Note that the Maple implementation comes from `newlib +<http://sourceware.org/newlib/>`_\ , while Arduino's is that of +`avr-libc <http://avr-libc.nongnu.org/>`_\ . + +See Also +-------- + +- :ref:`cos <lang-cos>` +- :ref:`tan <lang-tan>` +- :ref:`float <lang-float>` +- :ref:`double <lang-double>` + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/api/sq.rst b/docs/source/lang/api/sq.rst new file mode 100644 index 0000000..96724d3 --- /dev/null +++ b/docs/source/lang/api/sq.rst @@ -0,0 +1,45 @@ +.. highlight:: cpp + +.. _lang-sq: + +sq() +==== + +(Macro) computes the square of a number. + +Syntax +------ + +:: + + sq(a) + +Parameters +---------- + +**a**: the number. + +Returns +------- + +**a** squared (**a** × **a**). + +Warning +------- + +Because of the way ``sq()`` is implemented, avoid using other +functions or causing side effects inside the parentheses, as it may +lead to incorrect results:: + + b = sq(a++); // avoid this - yields incorrect results + + b = sq(a); // use this instead - + a++; // keep other operations outside sq() + + +Arduino Compatibility +--------------------- + +Maple's implementation of ``sq()`` is compatible with Arduino. + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/api/tan.rst b/docs/source/lang/api/tan.rst new file mode 100644 index 0000000..b1aed31 --- /dev/null +++ b/docs/source/lang/api/tan.rst @@ -0,0 +1,30 @@ +.. _lang-tan: + +tan() +===== + +Calculates the tangent of an angle. + +Library Documentation +--------------------- + +.. doxygenfunction:: tan + +Arduino Compatibility +--------------------- + +The Maple version of ``tan()`` is compatible with Arduino. + +Note that the Maple implementation comes from `newlib +<http://sourceware.org/newlib/>`_\ , while Arduino's is that of +`avr-libc <http://avr-libc.nongnu.org/>`_\ . + +See Also +-------- + +- :ref:`sin <lang-sin>` +- :ref:`cos <lang-cos>` +- :ref:`float <lang-float>` +- :ref:`double <lang-double>` + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/api/toggleled.rst b/docs/source/lang/api/toggleled.rst new file mode 100644 index 0000000..cad347f --- /dev/null +++ b/docs/source/lang/api/toggleled.rst @@ -0,0 +1,37 @@ +.. highlight:: cpp + +.. _lang-toggleled: + +toggleLED() +=========== + +*Toggle* the built-in LED: switch it from off to on, or on to off. + +Library Documentation +--------------------- + +.. doxygenfunction:: toggleLED + +Example +------- + +.. _lang-toggleled-example: + +This example sets up the board's LED pin for output, then toggles the +LED every 100 milliseconds:: + + void setup() { + pinMode(BOARD_LED_PIN, OUTPUT); + } + + void loop() { + toggleLED(); + delay(100); + } + + +See Also +-------- + +- :ref:`BOARD_LED_PIN <lang-board-values-led>` +- :ref:`togglePin() <lang-togglepin>` diff --git a/docs/source/lang/api/togglepin.rst b/docs/source/lang/api/togglepin.rst new file mode 100644 index 0000000..290718d --- /dev/null +++ b/docs/source/lang/api/togglepin.rst @@ -0,0 +1,17 @@ +.. _lang-togglepin: + +togglePin() +=========== + +Switches a digital output pin from :ref:`HIGH <lang-constants-high>` +to :ref:`LOW <lang-constants-low>`, or from LOW to HIGH. + +Library Documentation +--------------------- + +.. doxygenfunction:: togglePin + +See Also +-------- + +- :ref:`toggleLED() <lang-toggleled>` diff --git a/docs/source/lang/api/volatile.rst b/docs/source/lang/api/volatile.rst new file mode 100644 index 0000000..1b72897 --- /dev/null +++ b/docs/source/lang/api/volatile.rst @@ -0,0 +1,65 @@ +.. highlight:: cpp + +.. _lang-volatile: + +``volatile`` +============ + +The ``volatile`` keyword known is a variable *qualifier*. It is +usually used before the datatype of a variable, to modify the way in +which the compiler treats the variable. + +Declaring a variable ``volatile`` is a directive to the compiler. The +compiler is software which translates your C++ code into the machine +code, which are the real instructions for the STM32 chip in the +Maple. (The particular compiler we provide for use with the Maple is a +version of :ref:`GCC <arm-gcc>`). + +Specifically, it directs the compiler to read the variable's value +fresh every time it is used, rather than "backing up" the value and +reading from its backup copy. (Compilers often "back up" a variable's +value in RAM into a storage location called a *register*; this is done +for efficiency). + +A variable should be declared ``volatile`` whenever its value can be +changed by something beyond the control of the code section in which +it appears, such as an :ref:`external interrupt +<external-interrupts>`. (The only place that this is likely to occur +in most programs is inside of code called by interrupts). + +Example +------- + +:: + + // toggles LED when interrupt pin changes state + + int pin = 13; + volatile int state = LOW; + + void setup() { + pinMode(pin, OUTPUT); + attachInterrupt(0, blink, CHANGE); + } + + void loop() { + digitalWrite(pin, state); + } + + void blink() { + if (state == HIGH) { + state = LOW; + } else { + // state must be HIGH + state = HIGH; + } + } + +See Also +-------- + +- :ref:`External Interrupts <external-interrupts>` +- :ref:`lang-attachinterrupt` +- :ref:`lang-detachinterrupt` + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/api/waitforbuttonpress.rst b/docs/source/lang/api/waitforbuttonpress.rst new file mode 100644 index 0000000..0e0fbaf --- /dev/null +++ b/docs/source/lang/api/waitforbuttonpress.rst @@ -0,0 +1,43 @@ +.. highlight:: cpp + +.. _lang-waitforbuttonpress: + +waitForButtonPress() +==================== + +Wait for the board's built-in button to be pressed, possibly with +timeout. The button is labeled "BUT" on the board's silkscreen. Its +pin number is the constant :ref:`BOARD_BUTTON_PIN +<lang-board-values-but>`. + +Library Documentation +--------------------- + +.. doxygenfunction:: waitForButtonPress + + +Example +------- + +.. _lang-waitforbuttonpress-example: + +This example sets up the board's button pin as an input, then prints a +message very time the button is pressed. + +:: + + void setup() { + pinMode(BOARD_BUTTON_PIN, INPUT); + } + + void loop() { + waitForButtonPress(); + SerialUSB.println("You pressed the button!"); + } + +See Also +-------- + +- :ref:`Board-specific values <lang-board-values>` +- :ref:`BOARD_BUTTON_PIN <lang-board-values-but>` +- :ref:`lang-isbuttonpressed` diff --git a/docs/source/lang/cc-attribution.txt b/docs/source/lang/cc-attribution.txt new file mode 100644 index 0000000..11302b2 --- /dev/null +++ b/docs/source/lang/cc-attribution.txt @@ -0,0 +1,10 @@ +.. Included in all this directory's files in order to satisfy the +.. Arduino CC Attribution-ShareAlike 3.0 License + +.. admonition:: License and Attribution + + Some information in this page was adapted from the `Arduino + Reference Documentation + <http://arduino.cc/en/Reference/HomePage>`_\ , which is released + under a `Creative Commons Attribution-ShareAlike 3.0 License + <http://creativecommons.org/licenses/by-sa/3.0/>`_. diff --git a/docs/source/lang/cpp/arithmetic.rst b/docs/source/lang/cpp/arithmetic.rst new file mode 100644 index 0000000..cef3954 --- /dev/null +++ b/docs/source/lang/cpp/arithmetic.rst @@ -0,0 +1,124 @@ +.. highlight:: cpp + +.. _lang-arithmetic: + +Arithmetic Operators (``+``, ``-``, ``*``, ``/``) +================================================= + +The operators ``+``, ``-``, ``*``, and ``/`` respectively evaluate to +the sum, difference, product, or quotient (respectively) of the two +operands. The operation is conducted using the data type of the +operands, so, for example, ``9 / 4`` gives ``2`` since 9 and 4 are +:ref:`int variables <lang-int>`. + +This also means that the operation can overflow if the result is +larger than that which can be stored in the data type (e.g. adding 1 +to an :ref:`lang-int` with the value 2,147,483,647 gives +-2,147,483,648). + +.. _lang-arithmetic-typeconversion: + +If the operands are of different types, the "larger" type is used for +the calculation. If one of the numbers (operands) are of the type +**float** or of type **double**, floating point math will be used for +the calculation. + +.. note:: The specifics of these rules are beyond the scope of this + documentation; for more information, see `The C++ Programming + Language <http://www2.research.att.com/~bs/3rd.html>`_\ , by Bjarne + Stroustroup, Appendix C, especially §§C.4-C.6, or `this WikiBooks + entry on C++ type conversion + <http://en.wikibooks.org/wiki/C%2B%2B_Programming/Programming_Languages/C%2B%2B/Code/Statements/Variables/Type_Casting#Automatic_type_conversion>`_. + +.. note:: For more information on how computers represent integers, + see the Wikipedia page on `two's complement + <http://en.wikipedia.org/wiki/Two's_complement>`_. + +.. contents:: Contents + :local: + +Examples +-------- + + :: + + y = y + 3; + x = x - 7; + i = j * 6; + r = r / 5; + + +Syntax +------ + + :: + + result = value1 + value2; + result = value1 - value2; + result = value1 * value2; + result = value1 / value2; + + +Parameters +---------- + +**value1**: any numeric variable or constant + +**value2**: any numeric variable or constant + +Programming Tips +---------------- + +- Know that :ref:`integer constants <lang-constants-integers>` + default to :ref:`int <lang-int>`, so some constant calculations + may overflow (e.g., 200000 * 5000000 will yield a negative result). + +- Choose variable sizes that are large enough to hold the largest + results from your calculations. + +- Know at what point your variable will "roll over" and also what + happens in the other direction e.g. (0 - 1) for unsigned arithmetic, + or (0 - -2,147,483,648) for signed arithmetic. + +- For math that requires fractions, float variables may be used, but + be aware of their drawbacks: large size and slow computation speeds + (the STM32 has no floating point hardware, so all floating point + calculations have to be done in software). + +- Use cast operator, e.g. ``(int)myFloat`` to convert one variable type + to another on the fly. + +Arduino Compatibility +--------------------- + +Since the STM32 processor on the Maple is a 32-bit machine, the int +type overflows at a much higher value on Maple than on Arduino. In +particular, on Maple, ints do not overflow (become negative) until +they reach 2,147,483,648; on the Arduino, they overflow at 32,767. +Because of this, programs running on Maple are much less likely to run +into overflow issues. The following table summarizes the sizes and +ranges of integer datatypes on the Maple (the ranges of ``long long`` +types are approximate): + +.. _lang-arithmetic-int-sizes: + +.. csv-table:: + :header: Datatype, Unsigned range, Signed range, Size (bytes) + :widths: 8, 12, 17, 8 + + ``char``, 0 --- 255, -128 --- 127, 1 + ``short``, "0 --- 65,535", "-32,768 --- 32,767", 2 + ``int``, "0 --- 4,294,967,295", "-2,147,483,648 --- 2,147,483,647", 4 + ``long``, "0 --- 4,294,967,295", "-2,147,483,648 --- 2,147,483,647", 4 + ``long long``, "0 --- 1.8*10\ :sup:`19`\ " (approx.), "-9.2*10\ :sup:`18` --- 9.2*10\ :sup:`18` (approx.)", 8 + + +See Also +-------- + +- The individual sizes (in bits) of various available types are + defined in :ref:`libmaple_types.h <libmaple-libmaple_types>`. + +- :ref:`sizeof <lang-sizeof>`\ () + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/cpp/array.rst b/docs/source/lang/cpp/array.rst new file mode 100644 index 0000000..39d4d91 --- /dev/null +++ b/docs/source/lang/cpp/array.rst @@ -0,0 +1,121 @@ +.. highlight:: cpp + +.. _lang-array: + +Arrays +====== + +An array is a collection of variables that are accessed with an index +number. Arrays in the C++ programming language, in which the Maple is +programmed, can be complicated, but using simple arrays is relatively +straightforward. + +.. contents:: Contents + :local: + +Creating (Declaring) an Array +----------------------------- + +All of the methods below are valid ways to create (declare) an +array. :: + + int myInts[6]; + int myPins[] = {2, 4, 8, 3, 6}; + int mySensVals[6] = {2, 4, -8, 3, 2}; + char message[6] = "hello"; + +You can declare an array without initializing it, as with myInts. In +the line referring to myPins, we declare an array without explicitly +choosing a size. The compiler counts the elements and creates an +array of the appropriate size. + +Finally, you can both initialize and size your array, as in +mySensVals. Note that when declaring an array with elements of type +char, one more element than your initialization is required, to hold +the required `null character <http://en.wikipedia.org/wiki/Null-terminated_string>`_. + + +Accessing an Array +------------------ + + +.. compound:: + + Arrays are **zero indexed**; that is, referring to the array + initialization above, the first element of the array is at index 0, + hence :: + + mySensVals[0] == 2; + mySensVals[1] == 4 + + and so forth. + +It also means that in an array with ten elements, index nine is the +last element. Hence:: + + int myArray[10]={9,3,2,4,3,2,7,8,9,11}; + // myArray[9] contains 11 + // myArray[10] is invalid and contains random information (other memory address) + +For this reason, you should be careful in accessing arrays. Accessing +past the end of an array (using an index number greater than your +declared array size - 1) is reading from memory that is in use for +other purposes. Reading from these locations is probably not going to +do much except yield invalid data. Writing to random memory locations +is definitely a bad idea, and can often lead to unhappy results such +as crashes or program malfunction. This can also be a difficult bug to +track down. + +Unlike Basic or Java, the C compiler does no checking to see if array +access is within legal bounds of the array size that you have +declared. + + +To assign a value to an array +----------------------------- + :: + + mySensVals[0] = 10; + + +To retrieve a value from an array +--------------------------------- + + :: + + x = mySensVals[4]; + + +Arrays and ``for`` Loops +------------------------ + +Arrays are often manipulated inside :ref:`for loops <lang-for>`, where +the loop counter is used as the index for each array element. For +example, to print the elements of an array over the serial port, you +could do something like this:: + + int i; + for (i = 0; i < 5; i = i + 1) { + SerialUSB.println(myPins[i]); + } + + +Example +------- + +For a complete program that demonstrates the use of arrays, see the +Arduino `Knight Rider example +<http://www.arduino.cc/en/Tutorial/KnightRider>`_\ (which will run +unmodified on the Maple). + +Arduino Compatibility +--------------------- + +Arrays on Maple are identical those on Arduino. + +See Also +-------- + +- :ref:`Storing arrays in FLASH memory <arm-gcc-attribute-flash>` + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/cpp/assignment.rst b/docs/source/lang/cpp/assignment.rst new file mode 100644 index 0000000..6379298 --- /dev/null +++ b/docs/source/lang/cpp/assignment.rst @@ -0,0 +1,60 @@ +.. highlight:: cpp + +.. _lang-assignment: + +Assignment Operator (``=``) +=========================== + +Stores the value to the right of the equal sign in the variable to +the left of the equal sign. + +The single equal sign in the C++ programming language is called the +assignment operator. It has a different meaning than in algebra +class, where it indicated an equation or equality. The assignment +operator tells the microcontroller to evaluate whatever value or +expression is on the right side of the equal sign, and store it in +the variable to the left of the equal sign [#fgross]_. + +Example +------- + +:: + + int sensVal; // declare an integer variable named sensVal + sensVal = analogRead(0); // store the (digitized) input voltage at analog pin 0 in sensVal + +Programming Tips +---------------- + +The variable on the left side of the assignment operator (``=`` sign) +needs to be able to hold the value stored in it. If it is not large +enough to hold a value, the value stored in the variable will be +incorrect. + +Don't confuse the assignment operator ``=`` (single equal sign) with +the comparison operator ``==`` (double equal signs), which evaluates +whether two expressions are equal. + +Arduino Compatibility +--------------------- + +Assignments on the Maple are identical to those on Arduino. + +See Also +-------- + +- :ref:`if <lang-if>` +- :ref:`char <lang-char>` +- :ref:`int <lang-int>` +- :ref:`long long <lang-longlong>` + +.. rubric:: Footnotes + +.. [#fgross] Experienced C++ programmers know this to be an + oversimplification of what happens when the variable on the left + hand side is an object. See Richard Gillam's wonderful and scary + `The Anatomy of the Assignment Operator + <http://icu-project.org/docs/papers/cpp_report/the_anatomy_of_the_assignment_operator.html>`_ + for more information. + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/cpp/bitshift.rst b/docs/source/lang/cpp/bitshift.rst new file mode 100644 index 0000000..47413f2 --- /dev/null +++ b/docs/source/lang/cpp/bitshift.rst @@ -0,0 +1,143 @@ +.. highlight:: cpp + +.. _lang-bitshift: + +Bit Shift Operators (``<<``, ``>>``) +==================================== + +(Adapted from `The Bit Math Tutorial +<http://www.arduino.cc/playground/Code/BitMath>`_ in `The Arduino +Playground <http://www.arduino.cc/playground/Main/HomePage>`_\ ) + +There are two bit shift operators in C++: the left shift operator +``<<`` and the right shift operator ``>>``. These operators cause the +bits in the left operand to be shifted left or right by the number of +positions specified by the right operand. + +More information on bitwise math can be obtained in the Wikipedia +article on `bitwise operations +<http://en.wikipedia.org/wiki/Bitwise_operation>`_\ , especially the +section on shifts in `C, C++, and Java +<http://en.wikipedia.org/wiki/Bitwise_operation#Shifts_in_C.2C_C.2B.2B.2C_C.23_and_Java>`_\ . + + +Syntax +------ + +``some_int << number_of_bits`` + +``some_int >> number_of_bits`` + + +Parameters +---------- + +* **some_int** An integer value or variable. + +* **number_of_bits** integer whose value is at most ``8 * + sizeof(variable)`` (so ``number_of_bits`` can be at most 32 for + ``int`` values, at most ``8`` for ``char`` values, etc.; the various + integer sizes are summarized :ref:`in this table + <lang-arithmetic-int-sizes>`\ ). + + + +Example: +-------- + +Here are some examples of bit shifting, with the binary representation of the number in comments:: + + int a = 5; // binary: 101 + int b = a << 3; // binary: 101000, or 40 in decimal + int c = b >> 3; // binary: 101, or back to 5 like we started with + + +When you left shift a value x by y bits (x << y), the leftmost y bits +in x are lost, literally shifted out of existence. We'll do this +example with ``char`` values (which are integers in the range 0-255, +and take up 8 bits of memory):: + + char a = 5; // binary (all 8 bits): 00000101 + char b = a << 7; // binary: 10000000 - the first 1 in 101 was discarded + + +If you are certain that none of the ones in a value are being shifted +into oblivion, a simple way to think of the left-shift operator is +that it multiplies the left operand by 2 raised to the right operand +power (in math notation, ``x << y`` equals x * 2\ :sup:`y`\ , as long +as none of the bits of x get shifted out). For example, to generate +powers of 2, the following expressions can be employed:: + + 1 << 0 == 1 + 1 << 1 == 2 + 1 << 2 == 4 + 1 << 3 == 8 + ... + 1 << 8 == 256 + 1 << 9 == 512 + 1 << 10 == 1024 + ... + +.. _lang-bitshift-signbit-gotcha: + +When you shift x right by y bits (``x >> y``), and the highest bit in +x is a 1, the behavior depends on the exact data type of x. If x is of +type ``int``, the highest bit is special, and determines whether x is +negative or not; the details are too complicated to explain here, but +they are thoroughly explained in the Wikipedia article on `two's +complement arithmetic +<http://en.wikipedia.org/wiki/Two%27s_complement>`_\ , which the +system most computers use to store integers. In that case, the sign +bit is copied into lower bits, for esoteric historical reasons:: + + int x = -16; // binary (all 32 bits): 11111111111111111111111111110000 + int y = x >> 3; // binary: 11111111111111111111111111111110 + + + +This behavior, called "sign extension", is often not what you +want. You probably wish zeros to be shifted in from the left. It +turns out that the right shift rules are different for ``unsigned +int`` values, so you can use a type cast to suppress ones being copied +from the left:: + + int x = -16; // binary: 11111111111111111111111111110000 + int y = (unsigned int)x >> 3; // binary: 00011111111111111111111111111110 + + + +If you are careful to avoid sign extension, you can use the +right-shift operator, ``>>``, as a way to divide by powers of 2. For +example:: + + int x = 1000; + int y = x >> 3; // integer division of 1000 by 8, causing y = 125. + + +Arduino Compatibility +--------------------- + +Since it's part of the C++ language, bit shifting on the Maple is +compatible with the Arduino; however, you should keep in mind that the +Maple has bigger integer types (as in, more bits) than the Arduino. + +Since the STM32 is a 32-bit processor, the ``int`` type takes up 32 +bits instead of 16, like on Arduino's 16-bit microcontroller. This +means that you can shift left, like ``x << y``, with bigger values of +``y`` on the Maple before ones in ``x`` start to get shifted out. + +To calculate the number of bits of an integer type on the Maple, +multiply its size in bytes (see :ref:`this table +<lang-arithmetic-int-sizes>` for these) by 8, since there are 8 +bits in 1 byte. For example, a ``short`` takes up 2 bytes of memory, +or 2 * 8 = 16 bits. + +See Also +-------- + +- :ref:`lang-bit` +- :ref:`lang-bitread` +- :ref:`lang-bitwrite` +- :ref:`lang-bitclear` + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/cpp/bitwisemath.rst b/docs/source/lang/cpp/bitwisemath.rst new file mode 100644 index 0000000..cfe34f2 --- /dev/null +++ b/docs/source/lang/cpp/bitwisemath.rst @@ -0,0 +1,185 @@ +.. highlight:: cpp + +.. _lang-bitwisemath: + +Bitwise Operators (``&``, ``|``, ``^``, ``~``) +============================================== + +The bitwise operators perform their calculations at the bit level of +variables. They help solve a wide range of common programming +problems. + +Much of the material here is adapted for Maple from an (Arduino) +`tutorial on bitwise math +<http://www.arduino.cc/playground/Code/BitMath>`_\ . Another great +resource is the Wikipedia article on `bitwise operations +<http://en.wikipedia.org/wiki/Bitwise_operation>`_\ . + +Below are descriptions and syntax for all of the operators. + +.. contents:: Contents + :local: + +.. _lang-bitwisemath-and: + +Bitwise AND (``&``) +------------------- + +The bitwise AND operator in C++ is a single ampersand, ``&``, used +between two other integer expressions. Bitwise AND operates on each +bit position of the surrounding expressions independently, according +to this rule: if both input bits are 1, the resulting output is 1, +otherwise the output is 0. Another way of expressing this is:: + + 0 0 1 1 operand1 + 0 1 0 1 operand2 + ---------- + 0 0 0 1 (operand1 & operand2) = result + + +On the Maple, the type ``int`` is a 32-bit value, so using ``&`` +between two ``int`` expressions causes 32 simultaneous AND operations +to occur. In a code fragment like:: + + int a = 92; // in binary: 00000000000000000000000001011100 + int b = 101; // in binary: 00000000000000000000000001100101 + int c = a & b; // result: 00000000000000000000000001000100, + // (or 68 in decimal). + + +Each of the 32 bits in ``a`` and ``b`` are processed using bitwise +AND, and all 32 resulting bits are stored in ``c``, resulting in the +value 1000100 in binary, which is 68 in decimal. + + +.. _lang-bitwisemath-or: + +Bitwise OR (``|``) +------------------ + +The bitwise OR operator in C++ is the vertical bar symbol, ``|``. Like +the ``&`` operator, ``|`` operates independently on each bit in its +two surrounding integer expressions, but what it does is +different. The bitwise OR of two bits is 1 if either or both of the +input bits is 1, otherwise it is 0. For example:: + + 0 0 1 1 operand1 + 0 1 0 1 operand2 + ---------- + 0 1 1 1 (operand1 | operand2) = result + +Here is an example of bitwise OR used in a snippet of C++ code (using +``char``, which takes up 8 bits of memory, instead of ``int``, which +uses 32):: + + char a = 92; // in binary: 01011100 + char b = 101; // in binary: 01100101 + char c = a | b; // result: 01111101, or 125 in decimal. + +.. _lang-bitwisemath-xor: + +Bitwise XOR (``^``) +------------------- + +There is a somewhat unusual operator in C++ called bitwise EXCLUSIVE +OR, also known as bitwise XOR. (In English, this is usually pronounced +"zor" or "ex-or"). The bitwise XOR operator is written using the caret +symbol, ``^``. This operator is very similar to the bitwise OR +operator ``|``, except it evaluates to 0 for a given bit position when +both of the input bits for that position are 1:: + + 0 0 1 1 operand1 + 0 1 0 1 operand2 + ---------- + 0 1 1 0 (operand1 ^ operand2) = result + + +Another way to look at bitwise XOR is that each bit in the result +is a 1 if the input bits are different, or 0 if they are the same. + +Here is a simple example:: + + int x = 12; // binary (ignoring extra bits): 1100 + int y = 10; // binary: 1010 + int z = x ^ y; // binary: 0110, or decimal 6 + + + +The ^ operator is often used to toggle (i.e. change from 0 to 1, or 1 +to 0) some of the bits in an integer expression. In a bitwise OR +operation if there is a 1 in the mask bit, that bit is inverted; if +there is a 0, the bit is not inverted and stays the same. Below is a +program to toggle the built-in LED pin (you can also accomplish this +with :ref:`lang-toggleled`):: + + // Toggle built-in LED pin + + int toggle = 0; + + // demo for Exclusive OR + void setup(){ + pinMode(BOARD_LED_PIN, OUTPUT); + } + + void loop(){ + toggle = toggle ^ 1; + digitalWrite(BOARD_LED_PIN, toggle); + delay(100); + } + +.. _lang-bitwisemath-not: + +Bitwise NOT (``~``) +------------------- + +The bitwise NOT operator in C++ is the tilde character ``~``. Unlike +``&`` and ``|``, the bitwise NOT operator is applied to a single +operand to its right. Bitwise NOT changes each bit to its opposite: 0 +becomes 1, and 1 becomes 0. For example:: + + 0 1 operand1 + ---- + 1 0 ~operand1 = result + +Another example:: + + char a = 103; // binary: 01100111 + char b = ~a; // binary: 10011000 = -104 + +You might be surprised to see a negative number like -104 as the +result of this operation. This is because the highest bit in an int +variable is the so-called "sign bit". If the highest bit is 1, the +number is interpreted as negative. This encoding of positive and +negative numbers is referred to as *two's complement*. For more +information, see the Wikipedia article on `two's +complement. <http://en.wikipedia.org/wiki/Twos_complement>`_ + +As an aside, it is interesting to note that (under two's complement +arithmetic) for any integer ``x``, ``~x`` is the same as ``-x-1``. + +At times, the sign bit in a signed integer expression can cause +some unwanted surprises. + + +Uses +---- + +One of the most common uses of bitwise operations is to select or +manipulate a particular bit (or bits) from an integer value, often +called `bit masking +<http://en.wikipedia.org/wiki/Mask_%28computing%29>`_\ . See the +linked Wikipedia article for more information and examples. + +If you really want to see bit-twiddling techniques in their full +glory, you could do much worse than to get yourself a copy of +`Hacker's Delight <http://www.hackersdelight.org/>`_\ . + + +See Also +-------- + +- :ref:`Boolean operations <lang-boolean>` (``&&``, ``||``) +- :ref:`Compound bitwise operations <lang-compoundbitwise>` (``&=``, + ``|=``, ``^=``). + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/cpp/boolean.rst b/docs/source/lang/cpp/boolean.rst new file mode 100644 index 0000000..f09345e --- /dev/null +++ b/docs/source/lang/cpp/boolean.rst @@ -0,0 +1,90 @@ +.. highlight:: cpp + +.. _lang-boolean: + +Boolean Operators +================= + +These can be used inside the condition of an :ref:`if <lang-if>` +statement. Evaluate to :ref:`true <lang-constants-true>` or +:ref:`false <lang-constants-false>`. + +.. contents:: Contents + :local: + +.. _lang-boolean-and: + +&& (logical and) +---------------- + +True only if both operands are true. For example:: + + if (digitalRead(2) == HIGH && digitalRead(3) == HIGH) { // read two switches + // ... + } + +is true only if both inputs are high. Another example:: + + if (a >= 10 && a <= 20){} // true if a is between 10 and 20 + +**Be careful** not to say ``10 <= a <= 20``! This won't work the way +you want. You have to separately test whether ``a`` is at least 10 +using ``a >= 10``, then test whether ``a`` is at most 20 using ``a <= +20``, then combine the results using ``&&``. + + +.. _lang-boolean-or: + +\|\| (logical or) +----------------- + +True if either operand is true. For example:: + + if (x > 0 || y > 0) { + // ... + } + +is true if either ``x`` or ``y`` is greater than 0. + +.. _lang-boolean-not: + +! (logical not) +--------------- + +True if the operand is false. For example:: + + if (!x) { + // ... + } + +is true if ``x`` is false (i.e. if ``x`` is zero). + +Some Advice +----------- + +.. warning:: + + Make sure you don't mistake the boolean AND operator ``&&`` + (double ampersand) for the :ref:`bitwise AND operator + <lang-bitwisemath-and>` ``&`` (single ampersand). They are + entirely different beasts. + + Similarly, do not confuse the boolean OR operator ``||`` (double + pipe) with the :ref:`bitwise OR operator <lang-bitwisemath-or>` + ``|`` (single pipe). + + The :ref:`bitwise NOT operator <lang-bitwisemath-not>` ``~`` + (tilde) looks much different than the boolean not operator ``!`` + (exclamation point, or "bang", as some programmers say), but you + still have to be sure which one you want. + + +See Also +-------- + +- :ref:`Bitwise operators <lang-bitwisemath>` (``&``, ``|``, ``^``, ``~``) +- :ref:`Compound bitwise operators <lang-compoundbitwise>` (``&=``, + ``|=``, ``^=``). +- :ref:`if statement <lang-if>` + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/cpp/booleanvariables.rst b/docs/source/lang/cpp/booleanvariables.rst new file mode 100644 index 0000000..e032c74 --- /dev/null +++ b/docs/source/lang/cpp/booleanvariables.rst @@ -0,0 +1,47 @@ +.. highlight:: cpp + +.. _lang-booleanvariables: + +Booleans +======== + +A **boolean** holds one of two values, :ref:`true +<lang-constants-true>` or :ref:`false <lang-constants-false>`. On a +Maple, each boolean variable has type ``bool``. + +.. warning:: + + On an Arduino, the type ``boolean`` is also provided. While the + Maple also has this type for compatibility, **its use is strongly + discouraged**. The ``bool`` type is a standard part of C++, while + ``boolean`` is a non-standard extension that serves no purpose. + +Example +------- + +:: + + // running is a boolean variable: + bool running = false; + + void setup() { + pinMode(BOARD_LED_PIN, OUTPUT); + pinMode(BOARD_BUTTON_PIN, INPUT); + } + + void loop() { + if (isButtonPressed()) { + // button is pressed + running = !running; // toggle running variable + digitalWrite(BOARD_LED_PIN, running) // indicate via LED + } + } + +See Also +-------- + +- :ref:`Boolean constants <lang-constants-bool>` +- :ref:`Boolean operators <lang-boolean>` +- :ref:`Variables <lang-variables>` + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/cpp/break.rst b/docs/source/lang/cpp/break.rst new file mode 100644 index 0000000..f367b99 --- /dev/null +++ b/docs/source/lang/cpp/break.rst @@ -0,0 +1,32 @@ +.. highlight:: cpp + +.. _lang-break: + +``break`` +========= + +``break`` is used to exit from a :ref:`while <lang-while>`\ , +:ref:`for <lang-for>`\ , or :ref:`do/while <lang-dowhile>` loop, +bypassing the normal loop condition. It is also used to exit from a +:ref:`switch <lang-switchcase>` statement. + + +Example +------- + +:: + + for (x = 0; x < 255; x ++) + { + digitalWrite(PWMpin, x); + sens = analogRead(sensorPin); + if (sens > threshold){ // bail out on sensor detect + x = 0; + // this line of code means that we'll immediately exit + // from the "for" loop: + break; + } + delay(50); + } + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/cpp/built-in-types.rst b/docs/source/lang/cpp/built-in-types.rst new file mode 100644 index 0000000..f14dce5 --- /dev/null +++ b/docs/source/lang/cpp/built-in-types.rst @@ -0,0 +1,108 @@ +.. highlight:: cpp + +.. _lang-built-in-types: + +================ + Built-in Types +================ + +This document serves as a reference for many of the built-in types +which are available when programming in the IDE. Programmers using +the :ref:`command-line tools <unix-toolchain>` will have access to +these types as long as they have imported `wirish.h +<https://github.com/leaflabs/libmaple/blob/master/wirish/wirish.h>`_; +several are defined in in `libmaple_types.h +<https://github.com/leaflabs/libmaple/blob/master/libmaple/libmaple_types.h>`_. + +.. _lang-built-in-types-integral: + +Integral types +-------------- + +.. cpp:type:: char + + 8-bit integer value. + +.. cpp:type:: short + + 16-bit integer value. + +.. cpp:type:: int + + 32-bit integer value. + +.. cpp:type:: long + + 32-bit integer value. + +.. cpp:type:: long long + + 64-bit integer value. + +.. cpp:type:: int8 + + 8-bit integer value. Synonym for ``signed char``. + +.. cpp:type:: uint8 + + 8-bit unsigned integer value. Synonym for ``unsigned char``. + +.. cpp:type:: byte + + 8-bit unsigned integer value. Synonym for ``unsigned char``. + +.. cpp:type:: int16 + + 16-bit integer value. Synonym for ``short``. + +.. cpp:type:: uint16 + + 16-bit unsigned integer value. Synonym for ``unsigned short``. + +.. cpp:type:: int32 + + 32-bit integer value. Synonym for ``int``. + +.. cpp:type:: uint32 + + Unsigned 32-bit integer value. Synonym for ``unsigned int`` + +.. cpp:type:: int64 + + 64-bit integer value. Synonym for ``long long`` + +.. cpp:type:: uint64 + + Unsigned 64-bit integer value. Synonym for ``unsigned long long``. + +Floating-Point Types +-------------------- + +.. cpp:type:: float + + 32-bit, IEEE-754 single-precision floating-point type. + +.. cpp:type:: double + + 64-bit, IEEE-754 double-precision floating-point type. + +Miscellaneous Types +------------------- + +.. cpp:type:: voidFuncPtr + + Pointer to a function that takes no arguments and returns nothing, i.e. :: + + typedef void (*voidFuncPtr)(void); + +.. cpp:type:: bool + + Boolean type. + +Other +----- + +.. cpp:type:: void + + Not really a type. To be honest with you, this only exists here to + silence warnings from our documentation build system. diff --git a/docs/source/lang/cpp/byte.rst b/docs/source/lang/cpp/byte.rst new file mode 100644 index 0000000..4634594 --- /dev/null +++ b/docs/source/lang/cpp/byte.rst @@ -0,0 +1,33 @@ +.. highlight:: cpp + +.. _lang-byte: + +byte +==== + +The ``byte`` type stores a 1-byte (8-bit) unsigned integer number, +from 0 to 255. + +.. warning:: + + The ``byte`` type is provided for compatibility with Arduino. + However, it is a non-standard extension. The standard C++ type for + storing an 8-bit unsigned integer is ``unsigned char``; we + recommend using that instead. (Your code will still work on an + Arduino). + + +Example +------- + +:: + + byte b = 134; + +See Also +-------- + +- :ref:`byte() <lang-bytecast>` (casting a value to a byte) +- :ref:`Variables <lang-variables>` + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/cpp/bytecast.rst b/docs/source/lang/cpp/bytecast.rst new file mode 100644 index 0000000..24c3b9e --- /dev/null +++ b/docs/source/lang/cpp/bytecast.rst @@ -0,0 +1,44 @@ +.. highlight:: cpp + +.. _lang-bytecast: + +byte() (cast) +============= + +Converts a value to the :ref:`byte <lang-byte>` data type. + +.. note:: + + Casting to the byte type is provided for compatibility with + Arduino. However, the recommended Maple type for storing an 8-bit + unsigned integer is ``uint8``. (C and C++ programmers: ``stdint.h`` + is also available). + + In order to cast a variable ``x`` to a ``uint8``, the + following syntax can be used:: + + uint8(x); + +Syntax +------ + +``byte(x)`` + +Parameters +---------- + +**x**: a value of any integer type + +Returns +------- + +The value, converted to a ``byte``. Note, however, that if the value +is larger than the maximum value you can store in a byte (255), then +the results might be strange and unexpected. + +See Also +-------- + +- :ref:`lang-byte` + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/cpp/cc-attribution.txt b/docs/source/lang/cpp/cc-attribution.txt new file mode 100644 index 0000000..e100140 --- /dev/null +++ b/docs/source/lang/cpp/cc-attribution.txt @@ -0,0 +1,9 @@ +.. Included in all this directory's files in order to satisfy the +.. Arduino CC Attribution-ShareAlike 3.0 License + +.. admonition:: License and Attribution + + This documentation page was adapted from the `Arduino Reference + Documentation <http://arduino.cc/en/Reference/HomePage>`_\ , which + is released under a `Creative Commons Attribution-ShareAlike 3.0 + License <http://creativecommons.org/licenses/by-sa/3.0/>`_. diff --git a/docs/source/lang/cpp/char.rst b/docs/source/lang/cpp/char.rst new file mode 100644 index 0000000..686c0d1 --- /dev/null +++ b/docs/source/lang/cpp/char.rst @@ -0,0 +1,44 @@ +.. highlight:: cpp + +.. _lang-char: + +``char`` +======== + +The ``char`` type stores a 1-byte character value (or integer with +value from -128 to 127). Character literals are written in single +quotes, like this: ``'A'`` (for multiple characters - strings - use +double quotes: ``"ABC"``). + +Just like everything else on a computer, characters are stored as +numbers. You can see the specific encoding in the `ASCII chart +<http://en.wikipedia.org/wiki/ASCII#ASCII_printable_characters>`_\ +. This means that it is possible to do arithmetic on characters, in +which the ASCII value of the character is used (e.g. ``'A' + 1`` has the +decimal value 66, since the ASCII value of the capital letter A in +decimal is 65). See the :ref:`Serial.println() +<lang-serial-println>` documentation for more information about how +characters are converted into numbers. + +The ``char`` datatype is a signed type, meaning that it encodes +numbers from -128 to 127. For an unsigned type, which stores values +from 0 to 255, just use the type ``unsigned char`` (two words). + +Example +------- + +:: + + // The following two lines are equivalent, using the ASCII + // character encoding: + char c = 'A'; + char c = 65; + +See Also +-------- + +- :ref:`lang-int` +- :ref:`lang-array` (a string is just an array of ``char``\ s) +- :ref:`Serial.println() <lang-serial-println>` + +.. include:: cc-attribution.txt diff --git a/docs/source/lang/cpp/charcast.rst b/docs/source/lang/cpp/charcast.rst new file mode 100644 index 0000000..640ad85 --- /dev/null +++ b/docs/source/lang/cpp/charcast.rst @@ -0,0 +1,32 @@ +.. highlight:: cpp + +.. _lang-charcast: + +``char()`` (cast) +================= + +Converts a value to the :ref:`char <lang-char>` data type. + +Syntax +------ + +``char(x)`` + +Parameters +---------- + +**x**: a value of any type + +Returns +------- + +The value, converted to a ``char``. Note, however, that if the value +is outside the range of a ``char`` (-128 to 127), then the results +might be strange and unexpected. + +See Also +-------- + +- :ref:`char <lang-char>` + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/cpp/comments.rst b/docs/source/lang/cpp/comments.rst new file mode 100644 index 0000000..1428dc3 --- /dev/null +++ b/docs/source/lang/cpp/comments.rst @@ -0,0 +1,64 @@ +.. highlight:: cpp + +.. _lang-comments: + +Comments +======== + +Comments are lines in the program that are used to inform yourself or +others about the way the program works. They are ignored by the +compiler, and not exported to the processor, so they don't take up any +space in RAM or Flash. + +One use for comments is to help you understand (or remember) how your +program works, or to inform others how your program works. There are +two different ways of making comments. + +.. _lang-comments-singleline: + +**Single line comment**: Anything following two slashes, ``//``, until +the end of the line, is a comment:: + + x = 5; // the rest of this line is a comment + +.. _lang-comments-multiline: + +**Multi-line comment**: Anything in between a pair of ``/*`` and ``*/`` +is a comment:: + + /* <-- a slash-star begins a multi-line comment + + all of this in the multi-line comment - you can use it to comment + out whole blocks of code + + if (gwb == 0){ // single line comment is OK inside a multi-line comment + x = 3; + } + + // don't forget the "closing" star-slash - they have to be balanced: + */ + +Note that it's okay to use single-line comments within a multi-line +comment, but you can't use multi-line comments within a multi-line +comment. Here's an example:: + + /* ok, i started a multi-line comment + + x = 3; /* this next star-slash ENDS the multi-line comment: */ + + x = 4; // this line is outside of the multi-line comment + + // next line is also outside of the comment, and causes a compile error: + */ + +Programming Tip +--------------- + +When experimenting with code, "commenting out" parts of your program +is a convenient way to remove lines that may be buggy. This leaves +the lines in the code, but turns them into comments, so the compiler +just ignores them. This can be especially useful when trying to locate +a problem, or when a program refuses to compile and the compiler error +is cryptic or unhelpful. + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/cpp/comparison.rst b/docs/source/lang/cpp/comparison.rst new file mode 100644 index 0000000..9cd0a9f --- /dev/null +++ b/docs/source/lang/cpp/comparison.rst @@ -0,0 +1,86 @@ +.. highlight:: cpp + +.. _lang-comparison: + +Comparison Operators (``==``, ``!=``, ``<``, ``>``, ``<=``, ``>=``) +=================================================================== + +The comparison operators ``==``, ``!=``, ``<``, ``>``, ``<=``, and +``>=`` are used to compare two numbers. They are :ref:`true +<lang-constants-true>` when the comparison is true, and :ref:`false +<lang-constants-false>` otherwise. They are based on the symbols +=, ≠, <, >, ≤, and ≥ from mathematics. + +Here are some examples, with their meaning in comments:: + + // "eq" is true when x is equal to y + bool eq = (x == y); + + // "neq" is true when x is different than y + bool neq = (x != y); + + // "lt" is true when x is less than, but NOT equal to, y + bool lt = (x < y); + + // "gt" is true when x is greater than, but NOT equal to, y + bool gt = (x > y); + + // "lte" is true when x is less than or equal to y + bool lte = (x <= y); + + // "gte" is true when x is greater than or equal to y + bool gte = (x >= y); + +The parentheses are optional; they are present only for clarity. For +example, the following two lines are the same:: + + bool eq = x == y; + + bool eq = (x == y); + +Uses +---- + +Comparison operators, along with :ref:`boolean operators +<lang-boolean>`, are useful inside the conditionals of :ref:`if +<lang-if>` statements. Here's one example:: + + if (x < 50) { + // only execute these lines if x is less than 50 + SerialUSB.println("delaying:"); + SerialUSB.println(x); + delay(x); + } + +.. warning:: + Beware of accidentally using the single equal sign (``=``) when you + meant to test if two numbers are equal (``==``). This is a common + mistake inside of ``if`` statement conditionals, e.g.:: + + // DON'T MAKE THIS MISTAKE + if (x = 10) { + // body + } + + The single equal sign is the assignment operator, and sets x to 10 + (puts the value 10 into the variable x). Instead use the double equal + sign (e.g. ``if (x == 10)``), which is the comparison operator, and + tests *whether* x is equal to 10 or not. The latter statement is only + true if x equals 10, but the former statement will always be true. + + This is because C evaluates the statement ``if (x=10)`` as follows: 10 + is assigned to x (remember that the single equal sign is the + :ref:`assignment operator <lang-assignment>`), so x now + contains 10. Then the 'if' conditional evaluates 10, which evaluates + to :ref:`true <lang-constants-true>`, since any non-zero number + evaluates to ``true``. + + Consequently, the conditional of an ``if`` statement like ``if (x = + 10) {...}`` will always evaluate to ``true``, and the variable x + will be set to 10, which is probably not what you meant. + + (This sometimes has uses, though, so just because an assignment + appears within a conditional doesn't mean it's automatically wrong. + Be careful to know what you mean.) + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/cpp/compoundarithmetic.rst b/docs/source/lang/cpp/compoundarithmetic.rst new file mode 100644 index 0000000..d70a43c --- /dev/null +++ b/docs/source/lang/cpp/compoundarithmetic.rst @@ -0,0 +1,43 @@ +.. highlight:: cpp + +.. _lang-compoundarithmetic: + +Compound Arithmetic Operators (``+=`` , ``-=``, ``*=``, ``/=``) +=============================================================== + +These oparators perform a mathematical operation on a variable with +another constant or variable. These operators are just a convenient +shorthand:: + + x += y; // equivalent to the expression x = x + y; + x -= y; // equivalent to the expression x = x - y; + x *= y; // equivalent to the expression x = x * y; + x /= y; // equivalent to the expression x = x / y; + +Here is an example:: + + int x = 2; + int y = 10; + + x += 4; // x now contains 6 + x -= 3; // x now contains 3 + x *= y; // x now contains 30 + x /= 2; // x now contains 15 + x += max(20, 6); // x now contains 35 + x -= sq(5); // x now contains 15 + +Parameters +---------- + +**x**: a numeric variable + +**y**: a numeric variable, number constant, or any other expression +that evaluates to a number (e.g. call to a function that returns a +number). + +See Also +-------- + +- :ref:`Arithmetic operators <lang-arithmetic>` + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/cpp/compoundbitwise.rst b/docs/source/lang/cpp/compoundbitwise.rst new file mode 100644 index 0000000..4efe5df --- /dev/null +++ b/docs/source/lang/cpp/compoundbitwise.rst @@ -0,0 +1,229 @@ +.. highlight:: cpp + +.. _lang-compoundbitwise: + +Compound Bitwise Operators (``&=``, ``|=``, ``^=``) +=================================================== + +The compound bitwise operators perform their calculations at the +bit level of variables. They are often used to clear and set +specific bits of a variable. + +See the :ref:`bitwise math tutorial <lang-bitwisemath>` for more +information on bitwise operators. + +.. contents:: Contents + :local: + +.. _lang-compoundbitwise-and: + +Compound bitwise AND (``&=``) +----------------------------- + +The compound bitwise AND operator ``&=`` is often used with a variable +and a constant to force particular bits in a variable to be zero. This +is often referred to in programming guides as "clearing" or +"resetting" bits. In a program, writing the line ``x &= y;`` is +equivalent to writing ``x = x & y;``. That is, the value of ``x`` +after the line will be equal to its old value bitwise ANDed with the +value of ``y``:: + + x &= y; // equivalent to x = x & y; + +You can use any integer variable for ``x`` (i.e., any variable of type +``int``, ``char``, ``byte``, ``long long``, etc.). You can use either +an integer variable or any :ref:`integer value +<lang-constants-integers>` (like ``3`` or ``0x20``) for ``y``. + +Before doing an example of ``&=``, let's first review the Bitwise AND +(``&``) operator:: + + 0 0 1 1 operand1 + 0 1 0 1 operand2 + ---------- + 0 0 0 1 (operand1 & operand2) = result + +As shown above, bits that are "bitwise ANDed" with 0 become 0, while +bits that are "bitwise ANDed" with 1 are left unchanged. So, if ``b`` +is a ``byte`` variable, then ``b & B00000000`` equals zero, and ``b & +B11111111`` equals ``b``. + +.. _lang-compoundbitwise-binconst: + +.. note:: The above uses :ref:`binary constants + <lang-constants-integers-bin>`\ . The numbers are still the same + value in other representations, they just might not be as easy to + understand. + + Normally, in C and C++ code, :ref:`hexadecimal + <lang-constants-integers-hex>` or :ref:`octal + <lang-constants-integers-oct>` are used when we're interested in + an integer's bits, rather than its value as a number. + + While hexadecimal and octal literals might be harder to understand + at first, you should really take the time to learn them. They're + part of C, C++, and many other programming languages, while binary + constants are available only for compatibility with Arduino. + + Also, ``B00000000`` is shown for clarity, but zero in any number + format is zero. + +So, to clear (set to zero) bits 0 and 1 of a one-byte variable, while +leaving the rest of the variable's bits unchanged, use the compound +bitwise AND operator ``&=`` with the constant ``B11111100`` +(hexadecimal ``0xFC``\ ):: + + 1 0 1 0 1 0 1 0 variable + 1 1 1 1 1 1 0 0 mask + ---------------------- + 1 0 1 0 1 0 0 0 + ^^^^^^^^^^^^^^^^ ^^^^ + unchanged cleared + + +Here is the same representation with the variable's bits replaced +with the symbol ``x``\ :: + + x x x x x x x x variable + 1 1 1 1 1 1 0 0 mask + ---------------------- + x x x x x x 0 0 + ^^^^^^^^^^^^^^^^ ^^^^ + unchanged cleared + + +So, using a byte variable ``b``\ , if we say:: + + b = B10101010; // B10101010 == 0xAA + b &= B11111100; // B11111100 == 0xFC + +then we will have :: + + b == B10101000; // B10101000 == 0xA8 + +.. _lang-compoundbitwise-or: + +Compound bitwise OR (``|=``) +---------------------------- + +The compound bitwise OR operator ``|=`` is often used with a variable +and a constant to "set" (set to 1) particular bits in a variable. In +a program, writing the line ``x |= y;`` is equivalent to writing ``x = +x | y;``. That is, the value of ``x`` after the line will be equal to +its old value bitwise ORed with the value of ``y``:: + + x |= y; // equivalent to x = x | y; + +You can use any integer variable for ``x`` (i.e., any variable of type +``int``, ``char``, ``long long`` etc.). You can use either an integer +variable or any integer value (like ``3`` or ``0x20``) for ``y``. +(This works the same way as :ref:`compound bitwise AND +<lang-compoundbitwise-and>`\ , ``&=``). + +Before doing an example of ``|=``, let's first review the Bitwise OR +(``|``) operator:: + + 0 0 1 1 operand1 + 0 1 0 1 operand2 + ---------- + 0 1 1 1 (operand1 | operand2) = result + +Bits that are "bitwise ORed" with 0 are unchanged, while bits that are +"bitwise ORed" with 1 are set to 1. So if ``b`` is a ``byte`` +variable, then ``b | B00000000`` equals ``b``, and ``b & B11111111`` +equals ``B11111111`` (here we've used binary constants; see the +:ref:`note <lang-compoundbitwise-binconst>` above). + +So, to set bits 0 and 1 of a one-byte variable, while leaving the rest +of the variable unchanged, use the compound bitwise OR operator +(``|=``) with the constant ``B00000011`` (hexadecimal ``0x3``):: + + 1 0 1 0 1 0 1 0 variable + 0 0 0 0 0 0 1 1 mask + ---------------------- + 1 0 1 0 1 0 1 1 + ^^^^^^^^^^^^^^^^ ^^^^ + unchanged set + +Here is the same representation with the variable's bits replaced with +the symbol ``x``:: + + x x x x x x x x variable + 0 0 0 0 0 0 1 1 mask + ---------------------- + x x x x x x 1 1 + ^^^^^^^^^^^^^^^^ ^^^^ + unchanged set + +So, using a byte variable ``b``, if we say:: + + b = B10101010; // B10101010 == 0xAA + b |= B00000011; // B00000011 == 0x3 + +then we will have :: + + b == B10101011; // B10101011 == 0xAB + +.. _lang-compoundbitwise-xor: + +Compound bitwise XOR (``^=``) +----------------------------- + +The compound bitwise XOR operator ``^=`` is used with a variable and a +constant to "toggle" (change 0 to 1, and 1 to 0) particular bits in a +variable. In a program, writing the line ``x ^= y;`` is equivalent to +writing ``x = x ^ y;``. That is, the value of ``x`` after the line +will be equal to its old value bitwise XORed with the value of ``y``:: + + x ^= y; // equivalent to x = x ^ y; + +You can use any integer variable for ``x`` (i.e., any variable of type +``int``, ``char``, ``long long``, etc.). You can use either an +integer variable or any integer value (like ``3`` or ``0x20``) for +``y``. (This works the same way as :ref:`&= +<lang-compoundbitwise-and>` and :ref:`\|= <lang-compoundbitwise-or>`; +in fact, these three operators all work the same in this way). + +Before doing an example of ``^=``, let's first review the Bitwise +XOR operator, ``^``:: + + 0 0 1 1 operand1 + 0 1 0 1 operand2 + ---------- + 0 1 1 0 (operand1 ^ operand2) = result + +One way to look at bitwise XOR is that each bit in the result is a 1 +if the input bits are different, or 0 if they are the same. Another +way to think about it is that the result bit will be 1 when *exactly* +one (no more, no less) of the input bits is 1; otherwise, it will be +zero. This means that if you XOR a bit with 1, it will change (or +toggle) its value, while if you XOR a bit with 0, it stays the same. + +So, to toggle bits 0 and 1 of a one-byte variable, while leaving the +rest of the variable unchanged, use the compound bitwise XOR operator +``^=`` with the constant ``B00000011`` (hexadecimal ``0x3``\ ; see +:ref:`note <lang-compoundbitwise-binconst>` above):: + + 1 0 1 0 1 0 1 0 variable + 0 0 0 0 0 0 1 1 mask + ---------------------- + 1 0 1 0 1 0 1 1 + ^^^^^^^^^^^^^^^^ ^^^^ + unchanged toggled + +So, using a byte variable ``b``, if we say:: + + b = B10101010; // B10101010 == 0xAA + b ^= B00000011; // B00000011 == 0x3 + +then we will have :: + + b == B10101001; // B10101001 == 0xA9 + +See Also +-------- + +- :ref:`Boolean operations <lang-boolean>` (``&&``, ``||``) +- :ref:`Bitwise operators <lang-bitwisemath>` (``&``, ``|``, ``^``, ``~``) + +.. include:: cc-attribution.txt diff --git a/docs/source/lang/cpp/const.rst b/docs/source/lang/cpp/const.rst new file mode 100644 index 0000000..ad0c580 --- /dev/null +++ b/docs/source/lang/cpp/const.rst @@ -0,0 +1,50 @@ +.. highlight:: cpp + +.. _lang-const: + +``const`` +========= + +The ``const`` keyword stands for "constant". It is a variable +*qualifier* that modifies the behavior of the variable, making a +variable "*read-only*". This means that the variable can be used just +as any other variable of its type, but its value cannot be +changed. You will get a compiler error if you try to assign a value to +a ``const`` variable. + +Constants defined with the ``const`` keyword obey the same rules of +:ref:`variable scoping <lang-scope>` that govern other +variables. This, and the pitfalls of using :ref:`#define +<lang-define>`, often makes using the ``const`` keyword a superior +method for defining constants than ``#define``. + +Example +------- + + :: + + // this defines a variable called "pi", which cannot be changed: + const float pi = 3.14; + float x; + + // .... + + x = pi * 2; // it's fine to find the value of a const variable + + pi = 7; // illegal - you can't write to (modify) a constant + +**#define** or **const** +------------------------ + +You can use either ``const`` or ``#define`` for creating numeric or +string constants. For :ref:`arrays <lang-array>`\ , you will need +to use ``const``. In general, ``const`` is preferred over ``#define`` +for defining constants. + +See Also +-------- + +- :ref:`#define <lang-define>` +- :ref:`volatile <lang-volatile>` + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/cpp/continue.rst b/docs/source/lang/cpp/continue.rst new file mode 100644 index 0000000..2a694f6 --- /dev/null +++ b/docs/source/lang/cpp/continue.rst @@ -0,0 +1,30 @@ +.. highlight:: cpp + +.. _lang-continue: + +``continue`` +============ + +The ``continue`` keyword skips the rest of the current iteration of a +:ref:`while <lang-while>`\ , :ref:`for <lang-for>`\ , or +:ref:`do/while <lang-dowhile>` loop. It continues by checking the +conditional expression of the loop, and proceeding with any subsequent +iterations. + +Example +------- + +:: + + + for (x = 0; x < 255; x ++) { + if (x > 40 && x < 120) { // create jump in values + continue; // skips the next two lines and goes to the + // beginning of the loop, with the next value of x + } + + digitalWrite(PWMpin, x); + delay(50); + } + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/cpp/curly-braces.rst b/docs/source/lang/cpp/curly-braces.rst new file mode 100644 index 0000000..df2fe2a --- /dev/null +++ b/docs/source/lang/cpp/curly-braces.rst @@ -0,0 +1,106 @@ +.. highlight:: cpp + +.. _lang-curly-braces: + +Curly Braces (``{``, ``}``) +=========================== + +.. contents:: Contents + :local: + +Introduction +------------ + +Curly braces (also referred to as just "braces" or as "curly +brackets") are a major part of the C and C++ programming +languages. They are used in several different constructs, outlined +below, and this can sometimes be confusing for beginners. + +An opening curly brace, ``{`` must always be followed by a closing +curly brace ``}``. This is a condition that is often referred to as +the braces being *balanced*. The Maple IDE (integrated development +environment) includes a convenient feature to check the balance of +curly braces. Just select a brace, or even click the insertion point +immediately following a brace, and its companion will be highlighted\ +[#fbug]_\ . + +Beginning programmers, and programmers coming to C++ from languages +without braces, often find using them confusing or daunting. + +Because the use of the curly brace is so varied, it is good +programming practice to type the closing brace immediately after +typing the opening brace when inserting a construct which requires +curly braces. Then insert some blank lines between your braces and +begin inserting statements. Your braces, and your attitude, will never +become unbalanced. + +Unbalanced braces can often lead to cryptic, impenetrable compiler +errors that can sometimes be hard to track down in a large program. +Because of their varied usages, braces are also incredibly important +to the syntax of a program and moving a brace one or two lines will +usually dramatically affect the meaning of a program. + +The main uses of curly braces +----------------------------- + +**Functions**:: + + // a function body needs braces around it + void myFunction(datatype argument) { + // ... function body goes in here ... + } + +**Loops** (see the :ref:`while <lang-while>`\ , :ref:`for +<lang-for>`\ , and :ref:`do/while <lang-dowhile>` loop reference +pages for more information):: + + // you should put braces around the body of a loop: + + while (boolean expression) { + // code inside the loop goes here + } + + for (initialisation; termination condition; incrementing expr) { + // code inside the loop goes here + } + + do { + // code inside the loop goes here + } while (boolean expression); + + +**Conditional statements** (see the :ref:`if statement <lang-if>` +reference page for more information):: + + // you should put braces around the body of an "if", "else if", + // or "else": + + if (boolean expression) { + // code inside the "if" + } + else if (boolean expression) { + // code inside the "else if" + } + else { + // code inside the "else" + } + +**Switch statements** (see the :ref:`switch statement +<lang-switchcase>` reference page for more information):: + + switch (var) { + case 1: + doThing1(); + break; + case 2: + doThing2(); + break; + } + +.. rubric:: Footnotes + +.. [#fbug] At present this feature is slightly buggy as the IDE will + often find (incorrectly) a brace in text that has been commented + out. + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/cpp/define.rst b/docs/source/lang/cpp/define.rst new file mode 100644 index 0000000..b22085f --- /dev/null +++ b/docs/source/lang/cpp/define.rst @@ -0,0 +1,54 @@ +.. highlight:: cpp + +.. _lang-define: + +``#define`` +=========== + +``#define`` is a useful C and C++ feature that allows the programmer +to give a name to a constant value before the program is compiled. +The compiler will replace references to these constants with the +defined value at compile time. + +This can have some unwanted side effects. In general, the :ref:`const +<lang-const>` keyword is preferred for defining constants. + +Syntax +------ + +The following line would define the name ``MY_CONSTANT`` to have value +``value``:: + + #define MY_CONSTANT value + +Note that the ``#`` is necessary. It is usually good style for the +name to be capitalized, although this is not required. + +There is no semicolon after the #define statement. If you include one, +the compiler will likely throw cryptic errors in unrelated places. +That is, **don't do this**:: + + // DON'T DO THIS! THE SEMICOLON SHOULDN'T BE THERE! + #define NAME value; + +Similarly, including an equal sign after the ``#define`` line will +also generate a cryptic compiler error further down the page. That +is, **don't do this, either**:: + + // DON'T DO THIS, EITHER! THE EQUALS SIGN SHOULDN'T BE THERE! + #define NAME = value + +Example +------- + + :: + + #define MAPLE_LED_PIN 13 + // The compiler will replace any mention of MAPLE_LED_PIN with + // the value 13 at compile time. + +See Also +-------- +- :ref:`const <lang-const>` + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/cpp/double.rst b/docs/source/lang/cpp/double.rst new file mode 100644 index 0000000..59422eb --- /dev/null +++ b/docs/source/lang/cpp/double.rst @@ -0,0 +1,46 @@ +.. _lang-double: + +``double`` +========== + +Double precision floating point type. Occupies 8 bytes. On Maple, the +``double`` type has a range of approximately -1.79769×10^308 to +1.79769×10^308; the ``double`` type subject to the same :ref:`overflow +issues <lang-variables-rollover>` as any numeric data type. + +Floating point numbers are not exact, and may yield strange results +when compared. For example ``6.0 / 3.0`` may not equal ``2.0``. You +should instead check that the absolute value of the difference between +the numbers is less than some small number. + +Floating point math is also much slower than integer math in +performing calculations, so should be avoided if, for example, a loop +has to run at top speed for a critical timing function. Programmers +often go to some lengths to convert floating point calculations to +integer math to increase speed. + +For more information, see the `Wikipedia article on floating point +math <http://en.wikipedia.org/wiki/Floating_point>`_\ . + +Floating-point numbers represent numbers with "decimal point", unlike +integral types, which always represent whole numbers. Floating-point +numbers are often used to approximate analog and continuous values +because they have greater resolution than integers. + +The double implementation on the Maple uses twice the number of bytes +as a :ref:`float <lang-float>`, with the corresponding gains in +precision. + +Tip +--- + +Users who borrow code from other sources that includes ``double`` +variables may wish to examine the code to see if the implied range and +precision are different from that actually achieved on the Maple. + +See Also +-------- + +- :ref:`float <lang-float>` + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/cpp/doublecast.rst b/docs/source/lang/cpp/doublecast.rst new file mode 100644 index 0000000..d3f32ce --- /dev/null +++ b/docs/source/lang/cpp/doublecast.rst @@ -0,0 +1,27 @@ +.. highlight:: cpp + +.. _lang-doublecast: + +``double()`` (cast) +=================== + +Converts a value to the :ref:`double <lang-double>` floating point +data type. Here is an example:: + + int x = 2; + double d = double(x); // d now holds 2.0, a double value + +The value ``x`` can be of any type. However, if ``x`` is not a number +(like an ``int`` or ``long long``), you will get strange results. + +See the :ref:`double <lang-double>` reference for details about the +precision and limitations of ``double`` values on the Maple. + +See Also +-------- + +- :ref:`double <lang-double>` +- :ref:`float <lang-float>` +- :ref:`float() <lang-floatcast>` + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/cpp/dowhile.rst b/docs/source/lang/cpp/dowhile.rst new file mode 100644 index 0000000..d229122 --- /dev/null +++ b/docs/source/lang/cpp/dowhile.rst @@ -0,0 +1,26 @@ +.. highlight:: cpp + +.. _lang-dowhile: + +``do``/``while`` +================ + +A ``do`` loop works in the same manner as a :ref:`while +<lang-while>` loop, with the exception that the condition is tested +at the end of the loop, so the ``do`` loop will *always* run at least +once. + +This is the basic syntax:: + + do { + // statement block + } while (test condition); + +Example:: + + do { + delay(50); // wait for sensors to stabilize + x = readSensors(); // check the sensors + } while (x < 100); + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/cpp/enum.rst b/docs/source/lang/cpp/enum.rst new file mode 100644 index 0000000..b6409eb --- /dev/null +++ b/docs/source/lang/cpp/enum.rst @@ -0,0 +1,52 @@ +.. highlight:: cpp + +.. _lang-enum: + +``enum`` +======== + +The ``enum`` keyword is used to specify an enumeration type. An +enumeration type is a type whose values are taken from a specified, +fixed list of constant values. + +Example +------- + +Here's an example defining an enumeration type called ``weather``, +which has values ``HOT``, ``COMFY``, and ``COLD``:: + + enum weather {HOT, COMFY, COLD}; + +Once you've defined this type, you can create variables of type +``weather``, in the same way you would with an :ref:`int <lang-int>`:: + + // create a weather variable named theWeather, with value COMFY: + weather theWeather = COMFY; + +Enumeration types are useful within :ref:`switch statements +<lang-switchcase>`. If you know that an argument is of an enumeration +type, you can make ``case`` statements for all of that type's possible +values, so you know you won't miss anything:: + + void describeWeather(weather currentWeather) { + switch(currentWeather) { + case HOT: + SerialUSB.println("it's hot out"); + break; + case COMFY: + SerialUSB.println("it's nice today"); + break; + case COLD: + SerialUSB.println("it's freezing!"); + break; + } + } + +Such a ``switch`` statement would need no :ref:`default +<lang-switchcase-default>`, since we know that ``currentWeather`` must +be either ``HOT``, ``COMFY``, or ``COLD``. + +See Also +-------- + +- :ref:`lang-switchcase` diff --git a/docs/source/lang/cpp/float.rst b/docs/source/lang/cpp/float.rst new file mode 100644 index 0000000..5195fac --- /dev/null +++ b/docs/source/lang/cpp/float.rst @@ -0,0 +1,50 @@ +.. highlight:: cpp + +.. _lang-float: + +``float`` +========= + +Single-precision floating point number. Occupies 4 bytes. On Maple, +the ``float`` type has a range of approximately -3.40282×10^38 to +3.40282×10^38; the ``float`` type is subject to the same +:ref:`overflow issues <lang-variables-rollover>` as any numeric data +type. + +``float``\ s have only 6-7 decimal digits of precision. That means the +total number of digits, not the number to the right of the decimal +point. You can get more precision by using a :ref:`double +<lang-double>` (which has a precision of about 16 decimal digits). + +The following example declares a ``float`` value named ``myfloat``:: + + float myfloat; + +This example declares a ``float`` value named ``sensorCalibrate``, +with value 1.117:: + + float sensorCalibrate = 1.117; + +The general syntax for declaring a float named ``var`` with value +``val`` is:: + + float var = val; + +Here is a more extended example involving a :ref:`float cast +<lang-floatcast>`:: + + int x; + int y; + float z; + + x = 1; + y = x / 2; // y now contains 0, ints can't hold fractions + z = float(x) / 2; // z now contains .5 + +See Also +-------- + +- :ref:`double <lang-double>` +- :ref:`Variables <lang-variables>` + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/cpp/floatcast.rst b/docs/source/lang/cpp/floatcast.rst new file mode 100644 index 0000000..af92543 --- /dev/null +++ b/docs/source/lang/cpp/floatcast.rst @@ -0,0 +1,28 @@ +.. highlight:: cpp + +.. _lang-floatcast: + +``float()`` (cast) +================== + +Converts a value to the :ref:`float <lang-float>` data type. Here is +an example (see the :ref:`constants reference <lang-constants-fp>` for +an explanation of the "2.0f"):: + + int x = 2; + float f = float(x); // f now holds 2.0f, a float value + +The value ``x`` can be of any type. However, if ``x`` is not a number +(like an ``int``), you will get strange results. + +See the :ref:`float <lang-float>` reference for details about the +precision and limitations of ``float`` values on the Maple. + +See Also +-------- + +- :ref:`float <lang-float>` +- :ref:`double <lang-double>` +- :ref:`double() <lang-doublecast>` + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/cpp/for.rst b/docs/source/lang/cpp/for.rst new file mode 100644 index 0000000..78ea562 --- /dev/null +++ b/docs/source/lang/cpp/for.rst @@ -0,0 +1,142 @@ +.. highlight:: cpp + +.. _lang-for: + +``for`` +======= + +A ``for`` loop is used to repeat a block of statements enclosed in +curly braces. ``for`` loops are useful for performing repetitive +operations, and are often used in combination with :ref:`arrays +<lang-array>` to operate on collections of data or multiple +:ref:`pins <gpio>`. A ``for`` loop is composed of two parts: first, a +*header*, which sets up the for loop, and then a *body*, which is made +up of lines of code enclosed in curly braces. + +.. contents:: Contents + :local: + +Syntax +------ + +There are three parts to the ``for`` loop header: an *initialization* +expression, *loop condition* expression, and a *post-loop* +expression. The general syntax looks like this:: + + for (initialization; condition; post-loop) { + // all of these lines inside the curly braces are part + // of the loop body. + statement 1; + statement 2; + ... + } + +(Note that there is no semicolon after the post-loop). The +initialization happens first and exactly once, before the loop begins. +Each time through the loop, the condition is tested. The condition is +a :ref:`boolean <lang-boolean>` expression. If it is true, then the +list of statements inside the curly braces are executed. Next, the +post-loop is executed. The loop then begins again by evaluating the +condition again, entering the loop body if it is true. This proceeds +until the condition becomes false. + +Examples +-------- + +Here's an example:: + + // Dim an LED using a PWM pin + int pwmPin = 9; // LED in series with 470 ohm resistor on pin 9 + + void setup() { + pinMode(pwmPin, PWM); + } + + void loop() { + for (int i=0; i <= 65535; i++) { + pwmWrite(pwmPin, i); + delay(1); + } + } + +There is a ``for`` loop In the :ref:`loop() <lang-loop>` function of +the above example. This loop starts by declaring an ``int`` variable +named ``i``, whose value starts out at zero. The loop proceeds by +checking if ``i`` is less than or equal to 65535. Since ``i`` is +zero, this is true, and so the calls to :ref:`pwmWrite() +<lang-pwmwrite>` and :ref:`delay() <lang-delay>` happen next. At this +point, the post-loop expression ``i++`` is evaluated, which +:ref:`increments <lang-increment>` ``i``, so that ``i`` becomes one. +That concludes the first time through the loop. Each "time through +the loop" is referred to as an *iteration*. + +The loop then jumps back to the beginning, checking the condition as +the beginning of its second iteration (initialization is skipped, +since this only happens once, before the first iteration). One is +less than 65535, so the loop statements are executed again. This +proceeds over and over until the iteration when ``i`` finally +reaches 65536. At that point, the condition is no longer true, so the +loop stops executing, and the ``loop()`` function returns. + +Here's another example, using a ``for`` loop to brighten and fade an +LED (see the :ref:`pwmWrite() <lang-pwmwrite>` reference for more +information):: + + int pwmPin = 9; // hook up the LED to pin 9 + void loop() { + int x = 1; + for (int i = 0; i >= 0; i += x) { + analogWrite(pwmPin, i); // controls the brightness of the LED + if (i == 65535) { + x = -1; // switch direction, so i starts decreasing + } + delay(1); + } + } + +Coding Tips +----------- + +The C ``for`` loop is more flexible than ``for`` loops found in some +other computer languages, including BASIC. Any or all of the three +header elements may be left blank, although the semicolons are +required. Also the statements for initialization, condition, and +post-loop can be any valid C statements, and use any C datatypes, +including :ref:`floating point numbers <lang-double>`. These types +of unusual ``for`` loops sometimes provide solutions to less-common +programming problems. + +For example, using a multiplication in the post-loop line will +generate a `geometric progression +<http://en.wikipedia.org/wiki/Geometric_progression>`_:: + + for(int x = 1; x <= 100; x = x * 2) { + SerialUSB.println(x); + } + + +This loop prints out the numbers 1, 2, 4, 8, ..., 64. Check +your understanding of ``for`` loops by answering the following two +questions (answers are in footnote [#fanswers]_\ ): + +1. How many iterations occur before the loop finishes? + +2. Why does it stop at 64? + +See Also +-------- + +- :ref:`while <lang-while>` loops +- :ref:`do <lang-dowhile>` loops + +.. rubric:: Footnotes + +.. [#fanswers] + 1. Seven. + + 2. After the seventh iteration, the post-loop causes ``x`` to + equal 128. This is larger than 100, so the loop condition is + false, and the loop stops. + + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/cpp/goto.rst b/docs/source/lang/cpp/goto.rst new file mode 100644 index 0000000..2c0b3b0 --- /dev/null +++ b/docs/source/lang/cpp/goto.rst @@ -0,0 +1,129 @@ +.. highlight:: cpp + +.. _lang-goto: + +Labels and ``goto`` +=================== + +A *label* gives a name to a line of code within a function. You can +label a line by writing a name for it, then a colon (``:``), before +the line starts. The ``goto`` keyword allows program flow to transfer +to a labeled line from anywhere within the same function. + +.. warning:: The use of ``goto`` is discouraged in C and C++ + programming. It is *never necessary* to use ``goto`` to write a + program. + + Unless you know what you're doing, using ``goto`` tends to + encourage code which is harder to debug and understand than + programs without ``goto`` that do the same thing. That said, + however, it's sometimes useful; :ref:`see below <goto-when-to-use>` + for a concrete example. + +Using Labels and goto +--------------------- + +Labels and ``goto`` are probably best explained through example. +Let's start with an example of how to label lines. The first line +(``int x = analogRead(some_pin);``) in the :ref:`loop <lang-loop>` +function below has label ``readpin``. The third line (``delay(x);``) +has label ``startdelay``. The second line (``SerialUSB.println(x);``) +does not have a label:: + + void loop() { + readpin: + int x = analogRead(some_pin); + SerialUSB.println(x); // for debugging + startdelay: + delay(x); + // ... more code ... + } + +Anything which can be a :ref:`variable <lang-variables>` name can +be a label. + +Let's say that we wanted to print ``x`` only if it was very large, say +at least 2000. We might want to do this just so anybody watching on a +:ref:`serial monitor <ide-serial-monitor>` would know they were in for +a longer wait than usual. We can accomplish this through the use of a +``goto`` statement that skips the printing if ``x`` is less than +2000:: + + void loop() { + readpin: + int x = analogRead(some_pin); + if (x < 2000) { + goto startdelay; + } + SerialUSB.println(x); // for debugging + startdelay: + delay(x); + // ... more code ... + } + +In this modified program, whenever ``x`` is less than 2000, the body +of the :ref:`if <lang-if>` statement in the second line is +executed. The ``goto`` statement inside the ``if`` body skips +straight to the line labeled ``startdelay``, passing over the line +doing the printing. + +A ``goto`` does not have to "move forwards"; it can go "backwards", +too. For example, the following program prints "5" forever (why?):: + + void loop() { + printfive: + SerialUSB.println(5); + goto printfive; + SerialUSB.println(6); + } + +.. _goto-when-to-use: + +When to Use goto +---------------- + +As mentioned above, use of ``goto`` is `generally discouraged +<http://en.wikipedia.org/wiki/Goto#Criticism_and_decline>`_. However, +when used with care, ``goto`` can simplify certain programs. One +important use case for ``goto`` is breaking out of deeply nested +:ref:`for <lang-for>` loops or :ref:`if <lang-if>` logic blocks. +Here's an example:: + + for(int r = 0; r < 255; r++) { + for(int g = 255; g > -1; g--) { + for(int b = 0; b < 255; b++) { + if (analogRead(0) > 250) { + goto bailout; + } + // more statements ... + } + // innermost loop ends here + } + } + bailout: + // more code here + +In the above example, whenever the :ref:`analog reading +<lang-analogread>` on pin 0 was greater than 250, the program would +jump to the line labeled ``bailout``, exiting all three loops at once. + +While there is already a :ref:`break <lang-break>` keyword for +breaking out of a loop, it will only break out of the *innermost* +loop. So, if instead of saying "``goto bailout;``", there was a +"``break;``" instead, the program would only exit from the loop with +header "``for(int b = 0; b < 255; b++)``". The program would continue +at the line which reads "``// innermost loop ends here``", which is +clearly undesirable if you wanted to leave all three loops at once. + +More examples of when ``goto`` is a good choice are given in Donald +Knuth's paper, "Structured Programming with go to Statements"; see +below for a link. + +See Also +-------- + +- Dijkstra, Edsger W. `Go To Statement Considered Harmful <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.92.4846&rep=rep1&type=pdf>`_ (PDF) + +- Knuth, Donald. `Structured Programming with go to Statements <http://pplab.snu.ac.kr/courses/adv_pl05/papers/p261-knuth.pdf>`_ (PDF) + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/cpp/if.rst b/docs/source/lang/cpp/if.rst new file mode 100644 index 0000000..f248b05 --- /dev/null +++ b/docs/source/lang/cpp/if.rst @@ -0,0 +1,121 @@ +.. highlight:: cpp + +.. _lang-if: + +``if``/``else`` +=============== + +An ``if`` statement is used to execute code when certain conditions +are met. The general syntax for an ``if`` statement is:: + + if (condition) { + body + } + +An ``if`` statement first tests whether its *condition* is true (such +as an input being above a certain number). If the condition is true, +the ``if`` statement executes its *body*, which is made up of lines of +code inside :ref:`curly braces <lang-curly-braces>`. If the condition +is false, the body is not executed. Here's a more concrete example:: + + if (someVariable > 50) { + // do something here + } + +The program tests to see if ``someVariable`` is greater than 50. If it +is, the program executes every line in the curly braces (which in the +above example does nothing, since the body is just the :ref:`comment +<lang-comments>` line "``// do something here``"). + +Put another way, if the statement in parentheses is true, the +statements inside the braces are run. If not, the program skips over +the code. + +An ``if`` statement's condition (which is inside the parentheses after +``if``) often uses one or more :ref:`boolean <lang-boolean>` or +:ref:`comparison <lang-comparison>` operators. + +Writing the if Body +------------------- + +The brackets may be omitted after an ``if`` statement's +conditional. If this is done, the next line (which ends in a +semicolon) becomes the only line in the body. The following three +``if`` statements all do the same thing:: + + if (x > 120) digitalWrite(pin, HIGH); + + if (x > 120) + digitalWrite(pin, HIGH); + + if (x > 120) { + digitalWrite(pin, HIGH); + } + +However, the following two examples are different:: + + // example 1: two lines of code in the if body + if (x > 120) { + digitalWrite(pin1, HIGH); + digitalWrite(pin2, HIGH); + } + + // example 2: one line of code in the if body, and + // another line of code after the if statement + if (x > 120) + digitalWrite(pin1, HIGH); // this is in the if body + digitalWrite(pin2, HIGH); // this is NOT in the if body + +In the first example, since the body is enclosed in curly braces, both +lines are included. In the second example, since the curly braces are +missing, only the first line is in the ``if`` body. + +``else`` +-------- + +``if``/\ ``else`` allows greater control over the flow of code than +the basic :ref:`if <lang-if>` statement, by allowing multiple tests to +be grouped together. For example, an :ref:`analog input +<lang-analogread>` could be tested, with one action taken if the input +was less than 500, and another action taken if the input was 500 or +greater. The code would look like this:: + + if (pinFiveInput < 500) { + // action A + } else { + // action B + } + +``else`` can precede another ``if`` test, so that multiple, mutually +exclusive tests can be run at the same time. + +Each test will proceed to the next one until a true test is +encountered. When a true test is found, its associated block of code +is run, and the program then skips to the line following the entire +if/else construction. If no test proves to be true, the default +``else`` block is executed, if one is present, and sets the default +behavior. + +Note that an ``else if`` block may be used with or without a +terminating ``else`` block, and vice-versa. An unlimited number of +such ``else if`` branches is allowed. Here is a code example:: + + if (pinFiveInput < 500) { + // do Thing A + } else if (pinFiveInput >= 1000) { + // do Thing B + } else { + // do Thing C + } + +Another way to express branching, mutually exclusive tests, is with a +:ref:`switch/case <lang-switchcase>` statement. + + +See Also +-------- + +- :ref:`boolean operators <lang-boolean>` +- :ref:`comparison operators <lang-comparison>` + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/cpp/include.rst b/docs/source/lang/cpp/include.rst new file mode 100644 index 0000000..163509d --- /dev/null +++ b/docs/source/lang/cpp/include.rst @@ -0,0 +1,70 @@ +.. highlight:: cpp + +.. _lang-include: + +``#include`` +============ + +``#include`` is used to include outside libraries in your sketch. +This gives the programmer access to a large group of standard C +libraries (groups of pre-made functions and data types), and also +libraries written especially for Maple. + +Example +------- + +This example (from the `Arduino LiquidCrystal Tutorial +<http://arduino.cc/en/Tutorial/LiquidCrystal>`_) includes a library +that is used to control :ref:`LCD displays +<libraries-liquid-crystal>`:: + + // include the library code: + #include <LiquidCrystal.h> + + // initialize the library with the numbers of the interface pins + LiquidCrystal lcd(12, 11, 5, 4, 3, 2); + + void setup() { + // set up the LCD's number of columns and rows: + lcd.begin(16, 2); + // Print a message to the LCD. + lcd.print("hello, world!"); + } + + void loop() { + // set the cursor to column 0, line 1 + // (note: line 1 is the second row, since counting begins with 0): + lcd.setCursor(0, 1); + // print the number of seconds since reset: + lcd.print(millis()/1000); + } + +Note that a ``#include`` line, like :ref:`#define <lang-define>`, +has **no semicolon**. The compiler will print strange error messages +if you add one. + +C Standard Library +------------------ + +The standard C library that comes with Maple is called `newlib +<http://sourceware.org/newlib/>`_. Its main sources of documentation +are its `main reference <http://sourceware.org/newlib/libc.html>`_ +page and its `math functions +<http://sourceware.org/newlib/libm.html>`_ reference page. Here's an +example that imports the math.h library in order to take the `cube +root <http://en.wikipedia.org/wiki/Cube_root>`_ of a number:: + + #include <math.h> + + void setup() { + // no setup necessary + } + + void loop() { + // "cbrt" stands for "cube root" + double cubeRootOf3 = cbrt(3.0); + // prints a number that is approximately the cube root of 3: + SerialUSB.println(cubeRootOf3); + } + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/cpp/increment.rst b/docs/source/lang/cpp/increment.rst new file mode 100644 index 0000000..c423d1a --- /dev/null +++ b/docs/source/lang/cpp/increment.rst @@ -0,0 +1,37 @@ +.. highlight:: cpp + +.. _lang-increment: + +Increment and Decrement Operators (``++``, ``--``) +================================================== + +These operators increment (add one to) or decrement (subtract one +from) a variable. If they come before the variable, they return its +new value; otherwise, they return its old value. + +Some quick examples:: + + x++; // adds one to x, and returns the old value of x + ++x; // adds one to x, and returns the new value of x + + x--; // decrement x by one and returns the old value of x + --x; // decrement x by one and returns the new value of x + +A more extended example:: + + x = 2; + y = ++x; // x now contains 3, y contains 3 + y = x--; // x contains 2 again, y still contains 3 + +.. warning:: Be careful! You cannot put a space in between the two + ``+`` or ``-`` signs. This example is broken:: + + // this line won't compile (notice the extra space): + int y = x+ +; + +See Also +-------- + +- :ref:`lang-compoundarithmetic` + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/cpp/int.rst b/docs/source/lang/cpp/int.rst new file mode 100644 index 0000000..fa63946 --- /dev/null +++ b/docs/source/lang/cpp/int.rst @@ -0,0 +1,68 @@ +.. highlight:: cpp + +.. _lang-int: + +``int`` +======= + +The ``int`` data type represents integers. Integers are your primary +data type for number storage, and store a 4 byte value. This yields a +range of -2,147,483,648 to 2,147,483,647 (minimum value of -2^31 and a +maximum value of (2^31) - 1; that's about negative 2 billion to +positive 2 billion). + +An ``int`` stores a negative number with a technique called `two's +complement math +<http://en.wikipedia.org/wiki/Two%27s_complement#Explanation>`_\ . +The highest bit in an ``int``, sometimes refered to as the "sign" bit, +flags the number as a negative number. (See the linked article on +two's complement for more information). + +The Maple takes care of dealing with negative numbers for you, so that +arithmetic operations work mostly as you'd expect. There can be an +:ref:`unexpected complication <lang-bitshift-signbit-gotcha>` in +dealing with the :ref:`bitshift right operator (>>) +<lang-bitshift>`, however. + +.. _lang-long: + +The ``long`` type is a synonym for ``int``. + +Here is an example of declaring an ``int`` variable named ``pin``, +then giving it value 13:: + + int pin = 13; + +The general syntax for declaring an ``int`` variable named ``var``, +then giving it value ``val``, looks like:: + + int var = val; + +.. _lang-int-overflow: + +Integer Overflow +---------------- + +When ``int`` variables leave the range specified above, they +:ref:`roll over <lang-variables-rollover>` in the other direction. +Here are some examples:: + + int x; + x = -2,147,483,648; + x--; // x now contains 2,147,483,647; rolled over "left to right" + + x = 2,147,483,647; + x++; // x now contains -2,147,483,648; rolled over "right to left" + +See Also +-------- + +- :ref:`unsigned int <lang-unsignedint>` +- :ref:`char <lang-char>` +- :ref:`unsigned char <lang-unsignedchar>` +- :ref:`long long <lang-longlong>` +- :ref:`unsigned long long <lang-unsignedlonglong>` +- :ref:`Integer Constants <lang-constants-integers>` +- :ref:`Variables <lang-variables>` + +.. include:: cc-attribution.txt diff --git a/docs/source/lang/cpp/intcast.rst b/docs/source/lang/cpp/intcast.rst new file mode 100644 index 0000000..da838c7 --- /dev/null +++ b/docs/source/lang/cpp/intcast.rst @@ -0,0 +1,26 @@ +.. highlight:: cpp + +.. _lang-intcast: + +``int()`` (cast) +================ + +Converts a value to the :ref:`int <lang-int>` data type. Here is +an example:: + + double d = 2.5; + int i = int(d); // i holds "2", an int value + +The value inside of the parentheses (``int(...)``) can be of any type. +However, if it is not a numeric type (like ``double``, ``char``, +etc.), you will get strange results. + +See the :ref:`int <lang-int>` reference for details about the +precision and limitations of ``int`` variables on the Maple. + +See Also +-------- + +- :ref:`int <lang-int>` + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/cpp/keywords.rst b/docs/source/lang/cpp/keywords.rst new file mode 100644 index 0000000..f21cd0d --- /dev/null +++ b/docs/source/lang/cpp/keywords.rst @@ -0,0 +1,204 @@ +.. _lang-keywords: + +Keywords +======== + +This page lists all of the C++ keywords, and either links to a +reference page explaining their use, or provides a brief description. + +List of Keywords +---------------- + +The C++ keywords are: + +``and``, ``and_eq``, ``asm``, ``auto``, ``bitand``, ``bitor``, +``bool``, ``break``, ``case``, ``catch``, ``char``, ``class``, +``compl``, ``const``, ``const_cast``, ``continue``, ``default``, +``delete``, ``do``, ``double``, ``dynamic_cast``, ``else``, ``enum``, +``explicit``, ``export``, ``extern``, ``false``, ``float``, ``for``, +``friend``, ``goto``, ``if``, ``inline``, ``int``, ``long``, +``mutable``, ``namespace``, ``new``, ``not``, ``not_eq``, +``operator``, ``or``, ``or_eq``, ``private``, ``protected``, +``public``, ``register``, ``reinterpret_cast``, ``return``, ``short``, +``signed``, ``sizeof``, ``static``, ``static_cast``, ``struct``, +``switch``, ``template``, ``this``, ``throw``, ``true``, ``try``, +``typedef``, ``typeid``, ``typename``, ``union``, ``unsigned``, +``using``, ``virtual``, ``void``, ``volatile``, ``wchar_t``, +``while``, ``xor``, ``xor_eq`` + +Boolean Operator Synonyms +------------------------- + +- ``and`` is a synonym for :ref:`&& <lang-boolean-and>`. +- ``not`` is a synonym for :ref:`\! <lang-boolean-not>`. +- ``not_eq`` is a synonym for :ref:`\!= <lang-comparison>`. +- ``or`` is a synonym for :ref:`|| <lang-boolean-or>`. + +Bitwise Operator Synonyms +------------------------- + +- ``and_eq`` is a synonym for :ref:`&= <lang-compoundbitwise-and>`. +- ``bitand`` is a synonym for (bitwise) :ref:`& <lang-bitwisemath-and>`. +- ``bitor`` is a synonym for :ref:`\| <lang-bitwisemath-or>`. +- ``compl`` is a synonym for :ref:`~ <lang-bitwisemath-not>`. +- ``or_eq`` is a synonym for :ref:`|= <lang-compoundbitwise-or>`. +- ``xor`` is a synonym for :ref:`^ <lang-bitwisemath-xor>`. +- ``xor_eq`` is a synonym for :ref:`^= <lang-compoundbitwise-xor>`. + +Constants +--------- + +- ``true`` and ``false`` are the :ref:`boolean constants + <lang-booleanvariables>`. + +Control Flow +------------ + +- ``break`` can exit out of a :ref:`switch statement + <lang-switchcase>` or a :ref:`for <lang-for>`, :ref:`do + <lang-dowhile>`, or :ref:`while <lang-while>` loop. + +- ``case`` defines alternatives in a :ref:`switch statement <lang-switchcase>`. + +- ``continue`` will move control flow to the next iteration of the + enclosing :ref:`for <lang-for>`, :ref:`do <lang-dowhile>`, or + :ref:`while <lang-while>` loop. + +- ``default`` defines the default alternative in a :ref:`switch + statement <lang-switchcase>`. + +- ``do`` introduces a :ref:`do <lang-dowhile>` loop. + +- ``else`` is used in :ref:`if statements <lang-if>`. + +- ``for`` introduces a :ref:`for <lang-for>` loop. + +- ``goto`` :ref:`jumps <lang-goto>` to a label. + +- ``if`` introduces an :ref:`if statement <lang-if>`. + +- ``return`` :ref:`transfers flow to a function's caller <lang-return>`. + +- ``switch`` introduces a :ref:`switch statement <lang-switchcase>`. + +- ``while`` introduces a :ref:`while <lang-while>` loop. + +Types +----- + +The following keywords are used for built-in types. + +- :ref:`bool <lang-booleanvariables>` +- :ref:`char <lang-char>` +- :ref:`double <lang-double>` +- :ref:`float <lang-float>` +- :ref:`int <lang-int>` +- :ref:`long <lang-long>` +- :ref:`short <lang-built-in-types-integral>` +- :ref:`void <lang-void>` (not really a type, but used in the absence + of one) + +The following keywords are used to introduce new types. + +- :ref:`enum <lang-enum>` + +Qualifiers +---------- + +- :ref:`static <lang-static>` can be used to declare persistent local + variables; it has other uses not documented here. + +- ``unsigned`` is used to specify an unsigned integral type. + Examples: :ref:`lang-unsignedint`, :ref:`lang-unsignedchar`. + +- :ref:`volatile <lang-volatile>` is useful when declaring variables + that may be modified by external interrupts. + +- :ref:`const <lang-const>` is used to define constants. + +Other +----- + +These keywords are not described in the Maple documentation. For more +information, consult a C++ reference. + +- ``asm`` is used to insert literal assembly language. + +- ``auto`` is used to declare that a variable has automatic storage. + +- ``catch`` is used in exception handling. Note that the default + flags we pass to :ref:`GCC <arm-gcc>` include ``-fno-exceptions``. + +- ``class`` is used to define classes. + +- ``const_cast`` is used in typecasting. + +- ``delete`` is used to free ``new``\ -allocated storage. Note that + dynamic memory allocation is not available by default on the Maple, + so you'll have to bring your own ``new`` and ``delete`` if you want + this. + +- ``dynamic_cast`` is used in typecasting. + +- ``explicit`` is used to declare constructors that can be called only + explicitly. + +- ``export`` declares a template definition accessible to other + compilation units. + +- ``extern`` can mark a declaration as a declaration and not a + definition, and also grant external linkage to a ``const`` or + ``typedef``. + +- ``friend`` is used to declare that certain functions have access to + a class's private variables. + +- ``inline`` is a compiler hint to inline a function. + +- ``mutable`` specifies that a member can be updated, even when a + member of a ``const`` object. + +- ``namespace`` declares a new namespace. + +- ``new`` dynamically allocates space for a value. Note that dynamic + memory allocation is not available by default on the Maple, so + you'll have to bring your own ``new`` and ``delete`` if you want + this. + +- ``operator`` is used to define type-specific operator overrides. + +- ``private`` declares a private class member. + +- ``protected`` declares a protected class member. + +- ``public`` declares a public class member. + +- ``register`` is a compiler hint to store a variable in a register. + +- ``reinterpret_cast`` is used in typecasting. + +- ``signed`` is the opposite of ``unsigned``. + +- ``static_cast`` is used in typecasting. + +- ``struct`` declares a new struct. + +- ``template`` introduces a template class, function, etc. + +- ``this`` is a pointer to the receiver object. + +- ``throw`` is used in exception handling. Note that the default + flags we pass to :ref:`GCC <arm-gcc>` include ``-fno-exceptions``. + +- ``try`` is used in exception handling. Note that the default + flags we pass to :ref:`GCC <arm-gcc>` include ``-fno-exceptions``. + +- ``typedef`` defines a type synonym. + +- ``union`` defines an untagged union. + +- ``using`` is a directive related to namespaces. + +- ``virtual`` declares a method which may be overridden. + +- ``wchar_t`` is the wide character type. diff --git a/docs/source/lang/cpp/longcast.rst b/docs/source/lang/cpp/longcast.rst new file mode 100644 index 0000000..493ad67 --- /dev/null +++ b/docs/source/lang/cpp/longcast.rst @@ -0,0 +1,27 @@ +.. highlight:: cpp + +.. _lang-longcast: + +``long()`` (cast) +================= + +Converts a value to the :ref:`long <lang-long>` data type. Here is +an example:: + + double d = 2.5; + long i = long(d); // i holds "2L", an long value + +The value inside of the parentheses (``long(...)``) can be of any type. +However, if it is not a numeric type (like ``double``, ``char``, +etc.), you will get strange results. + +See the :ref:`long <lang-long>` reference for details about the +precision and limitations of ``long`` variables on the Maple. + +See Also +-------- + +- :ref:`long <lang-long>` +- :ref:`long long <lang-longlong>` + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/cpp/longlong.rst b/docs/source/lang/cpp/longlong.rst new file mode 100644 index 0000000..d942cb4 --- /dev/null +++ b/docs/source/lang/cpp/longlong.rst @@ -0,0 +1,56 @@ +.. highlight:: cpp + +.. _lang-longlong: + +``long long`` +============= + +The ``long long`` data type stores extended size integer values. You +can use a ``long long`` when your values are too large to fit into an +:ref:`int <lang-int>`. A ``long long`` occupies 8 bytes of memory. +This yields a range of approximately -9.2×10^18 to 9.2×10^18 (that's +9.2 billion billion, or about 92 million times the number of stars in +the Milky Way galaxy). The exact range of a ``long long`` on the +Maple is from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807, +or -2^63 to (2^63-1). A ``long long`` it is subject to the same +:ref:`overflow issues <lang-variables-rollover>` as any numeric data +type. + +A synonym for the ``long long`` type is ``int64``. + +Here's an example of declaring a long long (see :ref:`integer +constants <lang-constants-integers-u-l>` for an explanation of the +"LL" at the end of the number):: + + // Speed of light in nanometers per second (approximate). + long long c = 299792458000000000LL; + +The general syntax for declaring an ``long long`` variable named ``var``, +then giving it value ``val``, looks like:: + + long long var = val; + +This is identical to the ``int`` syntax, with ``long long`` (or, at +your option, ``int64``) replacing ``int``. + +Note that ``long long`` values will still :ref:`overflow +<lang-int-overflow>`, just like ``int`` values, but their much larger +range makes this less likely to happen. + +The downside to using a ``long long`` instead of an ``int`` (besides +the extra storage) is that :ref:`arithmetic <lang-arithmetic>` +operations on ``long long``\ s will take slightly longer than on +``int``\ s. + +See Also +-------- + +- :ref:`char <lang-char>` +- :ref:`unsigned char <lang-unsignedchar>` +- :ref:`int <lang-int>` +- :ref:`unsigned int <lang-unsignedint>` +- :ref:`unsigned long long <lang-unsignedlonglong>` +- :ref:`Integer Constants <lang-constants-integers>` +- :ref:`Variables <lang-variables>` + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/cpp/modulo.rst b/docs/source/lang/cpp/modulo.rst new file mode 100644 index 0000000..013d07e --- /dev/null +++ b/docs/source/lang/cpp/modulo.rst @@ -0,0 +1,70 @@ +.. highlight:: cpp + +.. _lang-modulo: + +Modulo Operator (``%``) +======================= + +Calculates the `remainder <http://en.wikipedia.org/wiki/Remainder>`_ +when one integer is divided by another. It is useful for keeping a +variable within a particular range (e.g. the size of an array). + +Syntax +------ + +:: + + dividend % divisor + +Parameters +---------- + +**dividend**: the number to be divided + +**divisor**: the number to divide by + +Returns +------- + +The remainder of **dividend**\ /\ **divisor**\ . + +Examples +-------- + +:: + + int x; + x = 7 % 5; // x now contains 2 + x = 9 % 5; // x now contains 4 + x = 5 % 5; // x now contains 0 + x = 4 % 5; // x now contains 4 + +:: + + /* update one value in an array each time through a loop */ + + int values[10]; + int i = 0; + + void setup() { + // no setup necessary + } + + void loop() { + values[i] = analogRead(0); + i = (i + 1) % 10; // modulo operator makes sure i stays between 0 and 9 + } + +Tip +--- + +The modulo operator does not work on floats. For that, you can use +the C standard library function `fmod() +<http://sourceware.org/newlib/libm.html#fmod>`_. + +See Also +-------- + +- :ref:`Arithmetic <lang-arithmetic>` + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/cpp/pointer.rst b/docs/source/lang/cpp/pointer.rst new file mode 100644 index 0000000..ff4ec32 --- /dev/null +++ b/docs/source/lang/cpp/pointer.rst @@ -0,0 +1,31 @@ +.. _lang-pointer: + +Pointer Operators (``&``, ``*``) +================================ + +The pointer operators ``&`` (reference) and ``*`` (dereference) are +different from the bitwise math operator :ref:`& +<lang-bitwisemath-and>` and the arithmetic operator :ref:`* +<lang-arithmetic>`. + +Pointers are one of the more complicated subjects for beginners in +learning C, and it is possible to write many useful Arduino sketches +without ever encountering pointers. However, for manipulating certain +data structures, the use of pointers can simplify the code, improve +its efficiency, and generally provide many benefits that would be +difficult to achieve without the use of pointers. + +Introducing pointers is somewhat outside the scope of this +documentation. However, a good `pointer tutorial +<http://www.cplusplus.com/doc/tutorial/pointers/>`_ is available. +Also see the `Wikipedia article on pointers +<http://en.wikipedia.org/wiki/Pointer_%28computing%29>`_, especially +the section on `pointers in C +<http://en.wikipedia.org/wiki/Pointer_%28computing%29#C_pointers>`_. + +See Also +-------- + +- http://xkcd.com/138/ + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/cpp/return.rst b/docs/source/lang/cpp/return.rst new file mode 100644 index 0000000..d9aecbe --- /dev/null +++ b/docs/source/lang/cpp/return.rst @@ -0,0 +1,60 @@ +.. highlight:: cpp + +.. _lang-return: + +``return`` +========== + +Terminates a function and return a value from a function to the +calling function, if the function has non-``void`` return type. + +Syntax: +------- + +:: + + // from within a "void" function: + return; + + // from within a non-"void" function: + return value; + +In the second case, ``value`` should have a type which is the same as +the return type of the function, or be convertible to it (like an +``int`` to a ``double``, etc.; see :ref:`this note +<lang-arithmetic-typeconversion>` for some references). + +Examples: +--------- + +A function to compare a sensor input to a threshold:: + + // converts analog readings between 0 and 400 to 0, and 400 up to 1. + int checkSensor() { + if (analogRead(0) > 400) { + return 1; + else { + return 0; + } + } + +An early ``return`` is also useful when testing a section of code +without having to "comment out" large sections of possibly buggy code, +like so:: + + void loop() { + + // brilliant code idea to test here + + return; + + // the rest of a dysfunctional sketch here + // this code will never be executed + } + +See Also +-------- + +- :ref:`comments <lang-comments>` + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/cpp/scope.rst b/docs/source/lang/cpp/scope.rst new file mode 100644 index 0000000..a270428 --- /dev/null +++ b/docs/source/lang/cpp/scope.rst @@ -0,0 +1,120 @@ +.. highlight:: cpp + +.. _lang-scope: + +Scope +===== + +Variables in the C++ programming language, which Maple uses (all of +your sketches are C++ programs in disguise), have a property called +*scope*. Simply put, a variable's scope is made up of all of the +lines where the variable can be used. + +Scope in C++ is a fairly complex topic, so we won't try to describe it +in full here. Instead, we present a simplified view, describing two +different kinds of scopes, *global* and *local*. For more detailed +information, consult a C++ reference. + +Global and Local Variables +-------------------------- + +A global variable is one that can be "seen" by every function in a +program. In the :ref:`Maple IDE <ide>`, any variable declared outside +of a function (like :ref:`setup() <lang-setup>` and :ref:`loop() +<lang-loop>`) is a global variable. + +A local variable can only be "seen" inside of a particular function. +You can declare a variable to be local to a function by declaring it +inside of the :ref:`curly braces <lang-curly-braces>` which enclose +that function. + +When programs start to get larger and more complex, local variables +are a useful way to ensure that a function has exclusive access to its +own variables. This prevents programming errors when one function +mistakenly modifies variables used by another function. + +It is also sometimes useful to declare and initialize a variable +inside a :ref:`for <lang-for>` loop. This creates a variable that +can only be accessed from inside the loop body. + +Example +------- + +Here is an example sketch (which you can copy into the Maple IDE and +run on your Maple) that illustrates the use of global and local +variables, as well as declaring variables inside of a ``for`` loop. +Be sure to open a :ref:`serial monitor <ide-serial-monitor>` after you +:ref:`verify <ide-verify>` and :ref:`upload <ide-upload>` the sketch:: + + int globalVar; // any function will see this variable + + void setup() { + // since "globalVar" is declared outside of any function, + // every function can "see" and use it: + globalVar = 50; + + // the variables "i" and "d" declared inside the "loop" function + // can't be seen here. see what happens when you uncomment the + // following lines, and try to Verify (compile) the sketch: + // + // i = 16; + // SerialUSB.print("i = "); + // SerialUSB.println(i); + // d = 26.5; + // SerialUSB.print("d = "); + // SerialUSB.println(d); + } + + void loop() { + // since "i" and "d" are declared inside of the "loop" function, + // they can only be seen and used from inside of it: + int i; + double d; + + for (int j = 0; j < 5; j++) { + // variable i can be used anywhere inside the "loop" function; + // variable j can only be accessed inside the for-loop brackets: + i = j * j; + SerialUSB.print("i = "); + SerialUSB.println(i); + } + + // globalVar can be accessed from anywhere. note how even + // though we set globalVar = 50 in the "setup" function, we can + // see that value here: + SerialUSB.print("globalVar = "); + SerialUSB.println(globalVar); + + // d can be accessed from anywhere inside the "loop" function: + d = 26.5; + SerialUSB.print("d = "); + SerialUSB.print(d); + SerialUSB.println(" (before separateFunction())"); + + separateFunction(); + + // notice how even though separateFunction() has a variable + // named "d", it didn't touch our (local) variable which has + // the same name: + SerialUSB.print("d = "); + SerialUSB.print(d); + SerialUSB.println(" (after separateFunction())"); + } + + void separateFunction() { + // variable "d" here has the same name as variable "d" inside of + // the "loop" function, but since they're both _local_ + // variables, they don't affect each other: + double d = 30.5; + SerialUSB.print("d = "); + SerialUSB.print(d); + SerialUSB.println(" (inside of separateFunction())"); + } + +See Also +-------- + +- `C++ programming Wikibook <http://en.wikibooks.org/wiki/C%2B%2B_Programming/Programming_Languages/C%2B%2B/Code/Statements/Scope>`_. +- Wikipedia article on `scope <http://en.wikipedia.org/wiki/Scope_%28programming%29>`_ + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/cpp/semicolon.rst b/docs/source/lang/cpp/semicolon.rst new file mode 100644 index 0000000..05e6218 --- /dev/null +++ b/docs/source/lang/cpp/semicolon.rst @@ -0,0 +1,22 @@ +.. highlight:: cpp + +.. _lang-semicolon: + +Semicolon (``;``) +================= + +Used to end a line of code. Example:: + + int a = 13; + +Tip +--- + +Forgetting to end a line in a semicolon will result in a compiler +error. The error text may be obvious, and refer to a missing +semicolon, or it may not. If an impenetrable or seemingly illogical +compiler error comes up, one of the first things to check is a +missing semicolon, in the immediate vicinity, preceding the line at +which the compiler complained. + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/cpp/sizeof.rst b/docs/source/lang/cpp/sizeof.rst new file mode 100644 index 0000000..ec2dea6 --- /dev/null +++ b/docs/source/lang/cpp/sizeof.rst @@ -0,0 +1,64 @@ +.. highlight:: cpp + +.. _lang-sizeof: + +``sizeof()`` +============ + +The ``sizeof`` operator on the Maple returns the number of bytes +needed to store a value of a given type\ [#fcharsize]_. This can be +an ordinary numeric type, like ``int``. It can be something more +complicated, like a ``struct`` or ``union``. If the argument to +``sizeof`` is an array, it returns the total number of bytes occupied +by the array. + +The general syntax looks like this:: + + sizeof(type) + sizeof(var) + +Example +------- + +The ``sizeof`` operator is useful for dealing with arrays (such as +strings) where it is convenient to be able to change the size of the +array without breaking other parts of the program. + +This program prints out a text string one character at a time. Try +changing the text phrase:: + + char myStr[] = "this is a test"; + int i; + + void setup() { + Serial.begin(9600); + } + + void loop() { + for (i = 0; i < sizeof(myStr) - 1; i++) { + Serial.print(i, DEC); + Serial.print(" = "); + Serial.println(myStr[i], BYTE); + } + } + + +Note that ``sizeof`` returns the total number of bytes. So for larger +variable types such as ``int``, the :ref:`for loop <lang-for>` +would look something like this:: + + for (i = 0; i < (sizeof(myInts)/sizeof(int)) - 1; i++) { + // do something with myInts[i] + } + +.. rubric:: Footnotes + +.. [#fcharsize] Technically (and pedantically) speaking, ``sizeof`` + returns a multiple of the number of bits a ``char`` occupies in + memory. However, on the Maple (this goes for most C++ + implementations), a ``char`` occupies 8 bits = 1 byte. All the C++ + standard guarantees, however, is that a ``char`` occupies at + *least* 8 bits. + +.. include:: /arduino-cc-attribution.txt + diff --git a/docs/source/lang/cpp/sqrt.rst b/docs/source/lang/cpp/sqrt.rst new file mode 100644 index 0000000..fbabf82 --- /dev/null +++ b/docs/source/lang/cpp/sqrt.rst @@ -0,0 +1,24 @@ +.. _lang-sqrt: + +sqrt() +====== + +Calculates the square root of a number. + +Library Documentation +--------------------- + +.. doxygenfunction:: sqrt + +Arduino Compatibility +--------------------- + +The Maple versino of ``sqrt()`` is compatible with Arduino. + +See Also +-------- + +- :ref:`pow <lang-pow>` +- :ref:`sq <lang-sq>` + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/cpp/static.rst b/docs/source/lang/cpp/static.rst new file mode 100644 index 0000000..8c52ba0 --- /dev/null +++ b/docs/source/lang/cpp/static.rst @@ -0,0 +1,56 @@ +.. highlight:: cpp + +.. _lang-static: + +``static`` +========== + +The ``static`` keyword can be used to create variables that are +visible to only one function. However, unlike local variables that get +created and destroyed every time a function is called, ``static`` +variables persist beyond the function call, preserving their data +between function calls. + +Variables declared as ``static`` will only be created and initialized +the first time a function is called. + +.. note:: This is only one use of the ``static`` keyword in C++. It + has some other important uses that are not documented here; consult + a reliable C++ reference for details. + +Example +------- + +One use case for ``static`` variables is implementing counters that +last longer than the functions which need them, but shouldn't be +shared to other functions. Here's an example:: + + void setup() { + SerialUSB.begin(); + } + + void loop() { + int reading; + if (timeToReadSensors()) { + reading = readSensors(); + } + // do something with reading + } + + int readSensors() { + static int numSensorReadings = 0; + numSensorReadings++; + if (numSensorReadings % 100 == 0) { + SerialUSB.print("just got to another 100 sensor readings"); + } + return analogRead(...); + } + +In this example, the static variable ``numSensorReadings`` is +initialized to zero the first time ``readSensors()`` is called, and +then incremented, so it starts out at one. Subsequent calls to +``readSensors()`` won't reset ``numSensorReadings`` to zero, because +it was declared ``static``. Thus, ``numSensorReadings`` is a count of +the number of times that ``readSensors()`` has been called. + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/cpp/string.rst b/docs/source/lang/cpp/string.rst new file mode 100644 index 0000000..3497484 --- /dev/null +++ b/docs/source/lang/cpp/string.rst @@ -0,0 +1,120 @@ +.. highlight:: cpp + +.. _lang-string: + +Strings +======= + +Text strings on the Maple can be represented with null-terminated +arrays of type :ref:`char <lang-char>`. + +Examples +-------- + +All of the following are valid declarations for strings:: + + char str1[15]; + char str2[6] = {'m', 'a', 'p', 'l', 'e'}; + char str3[6] = {'m', 'a', 'p', 'l', 'e', '\0'}; + char str4[ ] = "maple"; + char str5[6] = "maple"; + char str6[15] = "maple"; + +As you can see, there are several methods available for declaring and +initializing strings: + +- Declare an array of ``char`` without initializing it, as with ``str1``. + +- Declare an array of ``char`` (with one extra ``char``) and the + compiler will add the required null character, as with ``str2``. + +- Explicitly add the null character (``'\0'``), as with ``str3``. + +- Initialize with a string constant in quotation marks (``"..."``); + the compiler will size the array to fit the string constant and a + terminating null character (``str4``). + +- Initialize the array with an explicit size and string constant, + (``str5``). + +- Initialize the array, leaving extra space for a larger string + (``str6``). + +Null Termination +---------------- + +Generally, strings are terminated with a null character (`ASCII +<http://en.wikipedia.org/wiki/ASCII>`_ code 0). This allows functions +(like ``SerialUSB.print()``) to tell where the end of a string is. +Otherwise, they would continue reading subsequent bytes of memory that +aren't actually part of the string. + +This means that your string needs to have space for one more character +than the text you want it to contain. That is why ``str2`` and +``str5`` need to be six characters, even though "maple" is only five +-- the last position is automatically filled with a NULL +character. ``str4`` will be automatically sized to six characters, one +for the extra null. In the case of ``str3``, we've explicitly included +the null character (written ``'\0'``) ourselves. + +Note that it's possible to have a string without a final null +character (e.g. if you had specified the length of ``str2`` as five +instead of six). This will break most functions that use strings, so +you shouldn't do it intentionally. If you notice something behaving +strangely (operating on characters not in the string), however, this +could be the problem. + +Single quotes or double quotes? +------------------------------- + +Strings are always defined inside double quotes (``"Abc"``) and +characters are always defined inside single quotes (``'A'``). + +Wrapping long strings +--------------------- + +You can wrap long strings like this:: + + char myString[] = "This is the first line" + " this is the second line" + " etcetera"; + +Arrays of Strings +----------------- + +It is often convenient, when working with large amounts of text, +such as a project with an LCD display, to setup an array of +strings. Because strings themselves are arrays, this is in actually +an example of a two-dimensional array. + +In the code below, the asterisk after the datatype char ``char *`` +indicates that this is an array of "pointers". All array names are +actually pointers, so this is required to make an array of arrays. +Pointers are one of the more esoteric parts of C for beginners to +understand, but it isn't necessary to understand pointers in detail to +use them effectively here:: + + char* myStrings[] = {"This is string 1", "This is string 2", + "This is string 3", "This is string 4", + "This is string 5", "This is string 6"}; + + void setup() { + SerialUSB.begin(); + } + + void loop() { + for (int i = 0; i < 6; i++) { + SerialUSB.println(myStrings[i]); + delay(500); + } + } + + +See Also +-------- + +- :ref:`array <lang-array>` +- :ref:`__attribute__ <arm-gcc-attribute-flash>` +- :ref:`Variables <lang-variables>` + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/cpp/switchcase.rst b/docs/source/lang/cpp/switchcase.rst new file mode 100644 index 0000000..e31ccf3 --- /dev/null +++ b/docs/source/lang/cpp/switchcase.rst @@ -0,0 +1,118 @@ +.. highlight:: cpp + +.. _lang-switchcase: + +``switch``\ /\ ``case`` +======================= + +Like :ref:`if <lang-if>` statements, A ``switch`` statement controls +program flow by allowing you to specify different code that should be +executed under various cases. + +The general syntax looks like this:: + + switch (var) { + case val1: + // statements + break; + case val2: + // statements + break; + ... + default: + // statements + } + +Where ``var`` is a variable whose value to investigate, and the +``val1``, ``val2`` after each ``case`` are constant values that +``var`` might be. + +Description +----------- + +A ``switch`` statement compares the value of a variable to the values +specified in ``case`` statements. When a ``case`` statement is found +whose value matches that of the variable, the code in that case +statement is run. + +Here's a more concrete example:: + + switch (var) { + case 1: + doThing1(); + break; + case 2: + doThing2(); + break; + } + afterTheSwitch(); + +In the above example, if ``var == 1``, then the code beginning on the +line after ``case 1`` gets executed. That is, if ``var`` is one, +``doThing1()`` gets called first, and then the ``break`` statement is +executed. + +The ``break`` keyword exits the ``switch`` statement, and is typically +used at the end of each ``case``. Since there is a ``break`` at the +end of ``case 1``, the ``switch`` statement exits, and the next line +to be run is the one which calls ``afterTheSwitch()``. + +Without a ``break``, the ``switch`` statement will continue executing +the following ``case`` expressions ("falling-through") until a +``break`` (or the end of the switch statement) is reached. Let's +pretend the ``switch`` looked like this instead:: + + switch (var) { + case 1: + doThing1(); + // no break statement anymore + case 2: + doThing2(); + break; + } + afterTheSwitch(); + +Now, if ``var`` is one, ``doThing1()`` gets executed like before. +However, without a ``break``, the code would continue to be executed +line-by-line, so ``doThing2()`` would be called next. At this point, +a ``break`` has been reached, so the program continues by calling +``afterTheSwitch()``. This is usually not what you want, which is why +each ``case`` usually has a ``break`` at the end. + +.. _lang-switchcase-default: + +Writing "``default:``" instead of a ``case`` statement allows you to +specify what to do if none of the ``case`` statements matches. Having +a ``default`` is optional (you can leave it out), but if you have one, +it must appear after all of the ``case`` statements. Let's add a +``default`` to the ``switch`` we've been discussing:: + + switch (var) { + case 1: + doThing1(); + break; + case 2: + doThing2(); + break; + default: + doSomethingElse(); + } + afterTheSwitch(); + +If ``var`` is one, then ``doThing1()`` gets called. If ``var`` is +two, ``doThing2()`` gets called. If ``var`` is anything else, +``doSomethingElse()`` gets called. As stated above, a ``default`` is +optional. If you're missing one and none of the ``case`` statements +match, the ``switch`` does nothing at all, as if it weren't there. + +``switch`` statements are often used with an :ref:`enum <lang-enum>` +value as the variable to compare. In this case, you can write down +all of the values the ``enum`` takes as ``case`` statements, and be +sure you've covered all the possibilities. + +See Also: +--------- + +- :ref:`if/else <lang-if>` + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/cpp/unsignedchar.rst b/docs/source/lang/cpp/unsignedchar.rst new file mode 100644 index 0000000..45fedeb --- /dev/null +++ b/docs/source/lang/cpp/unsignedchar.rst @@ -0,0 +1,32 @@ +.. highlight:: cpp + +.. _lang-unsignedchar: + +``unsigned char`` +================= + +An unsigned version of the :ref:`char <lang-char>` data type. An +``unsigned char`` occupies 1 byte of memory; it stores an integer from +0 to 255. + +Like an :ref:`unsigned int <lang-unsignedint>`, an ``unsigned char`` +won't store negative numbers; it is also subject to the same +:ref:`overflow issues <lang-int-overflow>` as any integral data type. + +Example +------- + + :: + + unsigned char c = 240; + +See Also +-------- + +- :ref:`byte <lang-byte>` +- :ref:`int <lang-int>` +- :ref:`array <lang-array>` +- :ref:`SerialUSB.println() <lang-serialusb-println>` +- :ref:`Serial.println() <lang-serial-println>` + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/cpp/unsignedint.rst b/docs/source/lang/cpp/unsignedint.rst new file mode 100644 index 0000000..f8ea473 --- /dev/null +++ b/docs/source/lang/cpp/unsignedint.rst @@ -0,0 +1,59 @@ +.. highlight:: cpp + +.. _lang-unsignedint: + +``unsigned int`` +================ + +An ``unsigned int`` (unsigned integer) is the same as an :ref:`int +<lang-int>` in that it stores a 4 byte integer value. However, +Instead of storing both negative and positive numbers, an ``unsigned +int`` can only store nonnegative values, yielding a range of 0 to +4,294,967,295 (the positive value is 2^32 - 1). + +The difference between an ``unsigned int`` and a (signed) ``int`` lies +in the way the highest bit, sometimes referred to as the "sign" bit, +is interpreted. In the case of the Maple ``int`` type (which is +signed), if the high bit is a "1", the number is interpreted as a +negative number, using a technique known as `two's complement math +<http://en.wikipedia.org/wiki/Two%27s_complement#Explanation>`_. The +bits in an an ``unsigned int`` are interpreted according to the usual +rules for converting `binary to decimal +<http://en.wikipedia.org/wiki/Binary_numeral_system#Counting_in_binary>`_. + +An ``unsigned int`` is subject to the same :ref:`overflow issues +<lang-int-overflow>` as a regular ``int``; the only difference is +that an ``unsigned int`` will "underflow" at 0, and "overflow" at +4,294,967,295. Here is some example code which illustrates this:: + + unsigned int x; + x = 0; + x--; // x now contains 4,294,967,295; rolled over "left to right" + x++; // x now contains 0; rolled over "right to left" + +.. _lang-unsignedlong: + +The ``unsigned long`` type is a synonym for ``unsigned int``. + +Here is an example of declaring an ``unsigned int`` variable named +``pin``, then giving it value 13:: + + unsigned int pin = 13; + +The general syntax for declaring an ``unsigned int`` variable named +``var``, then giving it value ``val``, looks like:: + + unsigned int var = val; + +See Also +-------- + +- :ref:`int <lang-int>` +- :ref:`char <lang-char>` +- :ref:`unsigned char <lang-unsignedchar>` +- :ref:`long long <lang-longlong>` +- :ref:`unsigned long long <lang-unsignedlonglong>` +- :ref:`Integer Constants <lang-constants-integers>` +- :ref:`Variables <lang-variables>` + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/cpp/unsignedlonglong.rst b/docs/source/lang/cpp/unsignedlonglong.rst new file mode 100644 index 0000000..a1143f0 --- /dev/null +++ b/docs/source/lang/cpp/unsignedlonglong.rst @@ -0,0 +1,43 @@ +.. highlight:: cpp + +.. _lang-unsignedlonglong: + +``unsigned long long`` +====================== + +An unsigned version of the :ref:`long long <lang-longlong>` data type. +An ``unsigned long long`` occupies 8 bytes of memory; it stores an +integer from 0 to 2^64-1, which is approximately 1.8×10^19 (18 +quintillion, or 18 billion billion). + +A synonym for the ``unsigned long long`` type is ``uint64``. + +Like an :ref:`unsigned int <lang-unsignedint>`, an ``unsigned long +long`` won't store negative numbers; it is also subject to the same +:ref:`overflow issues <lang-int-overflow>` as any integral data type. + +Here is an example of declaring an ``unsigned long long`` variable +named ``c``, then giving it value 299,792,458,000,000,000 (see +:ref:`integer constants <lang-constants-integers-u-l>` for an +explanation of the "ULL" at the end of the number):: + + // Speed of light in nanometers per second (approximate). + unsigned long long c = 299792458000000000ULL; + +The general syntax for declaring an ``unsigned long long`` variable named +``var``, then giving it value ``val``, looks like:: + + unsigned long long var = val; + +See Also +-------- + +- :ref:`long long <lang-longlong>` +- :ref:`int <lang-int>` +- :ref:`unsigned <lang-unsignedint>` +- :ref:`char <lang-char>` +- :ref:`unsigned char <lang-unsignedchar>` +- :ref:`Integer Constants <lang-constants-integers>` +- :ref:`Variables <lang-variables>` + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/cpp/variables.rst b/docs/source/lang/cpp/variables.rst new file mode 100644 index 0000000..9ffdd1d --- /dev/null +++ b/docs/source/lang/cpp/variables.rst @@ -0,0 +1,169 @@ +.. highlight:: cpp + +.. _lang-variables: + +Variables +========= + +A variable is a way of naming and storing a value for later use by +the program, such as data from a sensor or an intermediate value +used in a calculation. + +.. contents:: Contents + :local: + +.. _lang-variables-declaring: + +Declaring Variables +------------------- + +Before they are used, all variables have to be *declared*. Declaring a +variable means defining its type, giving it a name, and (optionally) +giving it an initial value (this is often referred to as +*initializing* the variable). Variables do not have to be initialized +(given a value) when they are declared, but it is good style to give +them an initial value whenever possible. + +Here is an example of declaring a variable named ``inputVariable1`` +with type :ref:`int <lang-int>` (the ``int`` type is used to store +integers, like -2, -1, 0, 1, etc.):: + + int inputVariable1; + +In the above declaration, we did not give the variable an initial +value. Here is another example, where we declare an ``int`` variable +named ``inputVariable2``, with an initial value of ``0``:: + + int inputVariable2 = 0; + +The Maple environment comes ready to use with many useful types of +variables. See the :ref:`built-in types <lang-built-in-types>` page +for more information. + +Here are a few examples of declaring variables of different types:: + + int lightSensVal; + char currentLetter; + unsigned long long speedOfLight = 186000ULL; + char errorMessage = {"choose another option"}; // see string + +Naming Variables +---------------- + +The rules for naming a variable are simple. Names for variables can +contain letters, numbers, and underscores (the underscore is the +:kbd:`_` character), and cannot begin with a number. So +``temperature_reading``, ``tempReading``, ``tempReading1``, and +``tempReading2`` are all valid variable names, but ``4_temp_readings`` +is not, because it begins with a number. + +You cannot choose a name for a variable that is one of the C++ +:ref:`keywords <lang-keywords>`. + +Variable names are case-sensitive, so "tempreading" and "tempReading" +are different variables. However, it is very bad style to write code +that chooses variables which are the same up to case. + +You should give your variables descriptive names, so as to make your +code more readable. Variable names like ``tiltSensor`` or +``pushButton`` help you (and anyone else reading your code) understand +what the variable represents. Variable names like ``var`` or +``value``, on the other hand, do little to make your code readable. + +.. _lang-variables-scope: + +Variable Scope +-------------- + +An important choice that programmers face is where (in the program +text) to declare variables. The specific place that variables are +declared influences how various functions in a program will "see" the +variable. This is called variable *scope*. See the :ref:`scope +reference <lang-scope>` for more information. + +.. _lang-variables-initializing: + +Initializing Variables +---------------------- + +Variables may be *initialized* (assigned a starting value) when they +are declared or not. It is always good programming practice however to +double check that a variable has valid data in it before it is used. +Using a variable before you give it a value is a common source of +bugs. + +.. _lang-variables-rollover: + +Variable Rollover +----------------- + +Every (numeric) type has a valid *range*. The range of a type is the +smallest and largest value that a variable of that type can store. +For example, the :ref:`int <lang-int>` type has a range of +-2,147,483,648 to 2,147,483,647 [#frange]_. + +When variables are made to exceed their range's maximum value, they +"roll over" back to their minimum value. Note that this happens in +both directions. It's like in the game *Pac-Man* -- when Pac-Man goes +past the right edge of the screen, he reappears on the left, and when +he goes past the left side of the screen, he reappears on the right:: + + int x; + x = -2,147,483,648; + x = x - 1; // x now contains -2,147,483,647; rolled over "left to right" + + x = 2,147,483,647; + x = x + 1; // x now contains -2,147,483,648; rolled over "right to left" + +Each numeric type's reference page includes its range. See the +:ref:`built-in types <lang-built-in-types>` reference for links to each +type's reference page. + +Using Variables +--------------- + +Once variables have been declared, they are given values using the +:ref:`assignment operator <lang-assignment>`, which is a single equals +sign, ``=``. The assignment operator tells the program to store the +value on the right side of the equals sign into the variable on the +left side:: + + inputVariable1 = 7; // sets variable named inputVariable1 to 7 + inputVariable2 = analogRead(2); // sets variable named inputVariable2 to + // the (digitized) input voltage read from + // analog pin #2 + +Once a variable has been set (assigned a value), you can test its +value to see if it meets certain conditions, or you can use its value +directly. For instance, the following code tests whether the +inputVariable2 is less than 100, then sets a delay based on +inputVariable2 (which, at that point, is at least 100):: + + if (inputVariable2 < 100) { + inputVariable2 = 100; + } + + delay(inputVariable2); + +See Also +-------- + +- :ref:`lang-scope` +- :ref:`lang-built-in-types` + +.. rubric:: Footnotes + +.. [#frange] This range might seem a little weird at first. The + reasons for this range of values have to do with the fact that an + ``int`` occupies 32 bits of memory, and the facts :: + + 2^31 = -2,147,483,648 + 2^31 - 1 = 2,147,483,647 + + + Why 2^31 instead of 2^32? Well, that has to do with `how ints are + (usually) stored + <http://en.wikipedia.org/wiki/Two%27s_complement>`_ on computers. + +.. include:: /arduino-cc-attribution.txt + diff --git a/docs/source/lang/cpp/void.rst b/docs/source/lang/cpp/void.rst new file mode 100644 index 0000000..7af0acd --- /dev/null +++ b/docs/source/lang/cpp/void.rst @@ -0,0 +1,31 @@ +.. highlight:: cpp + +.. _lang-void: + +``void`` +======== + +.. cpp:type:: void + + The ``void`` keyword is used in function declarations. It indicates + that the function is expected to return no information to the + function from which it was called, or that it expects no arguments + from its caller. + +Example +------- + +:: + + // actions are performed in the functions "setup" and "loop" + // but no information is reported to the larger program + + void setup() { + // ... + } + + void loop() { + // ... + } + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/cpp/while.rst b/docs/source/lang/cpp/while.rst new file mode 100644 index 0000000..e66e0aa --- /dev/null +++ b/docs/source/lang/cpp/while.rst @@ -0,0 +1,38 @@ +.. highlight:: cpp + +.. _lang-while: + +``while`` +========= + +Syntax +------ + +:: + + while (expression) { + // block of code + } + +Description +----------- + +``while`` loops will repeat the statements inside their associated +block of code until the expression inside the parentheses becomes +:ref:`false <lang-constants-false>`. Something must change the tested +expressions' value, or the ``while`` loop will never exit. This could +be in your code, such as an incremented variable, or an external +condition, such as testing a sensor. + +Example +------- + +:: + + var = 0; + while(var < 200) { + // do something repetitive 200 times + var++; + } + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/lang/unimplemented/notone.rst b/docs/source/lang/unimplemented/notone.rst new file mode 100644 index 0000000..8af878b --- /dev/null +++ b/docs/source/lang/unimplemented/notone.rst @@ -0,0 +1,37 @@ +.. _lang-notone: + +noTone() +======== + +Description +----------- + +Stops the generation of a square wave triggered by +`tone <http://arduino.cc/en/Reference/Tone>`_\ (). Has no effect if +no tone is being generated. + +**NOTE:** if you want to play different pitches on multiple pins, +you need to call noTone() on one pin before calling tone() on the +next pin. + +Syntax +------ + +noTone(pin) + +Parameters +---------- + +pin: the pin on which to stop generating the tone + +Returns +------- + +Nothing. + +See Also +-------- + +- `tone <http://arduino.cc/en/Reference/Tone>`_ () + +.. include:: /lang/cc-attribution.txt diff --git a/docs/source/lang/unimplemented/pulsein.rst b/docs/source/lang/unimplemented/pulsein.rst new file mode 100644 index 0000000..2b52428 --- /dev/null +++ b/docs/source/lang/unimplemented/pulsein.rst @@ -0,0 +1,82 @@ +.. _lang-pulsein: + +pulseIn() +========= + +Description +----------- + +Reads a pulse (either HIGH or LOW) on a pin. For example, if +**value** is **HIGH**, **pulseIn()** waits for the pin to go +**HIGH**, starts timing, then waits for the pin to go **LOW** and +stops timing. Returns the length of the pulse in microseconds. +Gives up and returns 0 if no pulse starts within a specified time +out. + + + +The timing of this function has been determined empirically and +will probably show errors in longer pulses. Works on pulses from 10 +microseconds to 3 minutes in length. + + + +Syntax +------ + +pulseIn(pin, value) +pulseIn(pin, value, timeout) + + + +Parameters +---------- + +pin: the number of the pin on which you want to read the pulse. +(*int*) + + + +value: type of pulse to read: either +`HIGH <http://arduino.cc/en/Reference/Constants>`_ or +`LOW <http://arduino.cc/en/Reference/Constants>`_. (*int*) + + + +timeout (optional): the number of microseconds to wait for the +pulse to start; default is one second (*unsigned long*) + + + +Returns +------- + +the length of the pulse (in microseconds) or 0 if no pulse started +before the timeout (*unsigned long*) + + + +Example +------- + +:: + + + + int pin = 7; + unsigned long duration; + + void setup() + { + pinMode(pin, INPUT); + } + + void loop() + { + duration = pulseIn(pin, HIGH); + } + + + + +.. include:: /lang/cc-attribution.txt diff --git a/docs/source/lang/unimplemented/stringclass.rst b/docs/source/lang/unimplemented/stringclass.rst new file mode 100644 index 0000000..b893e83 --- /dev/null +++ b/docs/source/lang/unimplemented/stringclass.rst @@ -0,0 +1,6 @@ +.. _lang-stringclass: + +String Class +============ + +.. include:: /lang/cc-attribution.txt diff --git a/docs/source/lang/unimplemented/stringobject.rst b/docs/source/lang/unimplemented/stringobject.rst new file mode 100644 index 0000000..e47ed7e --- /dev/null +++ b/docs/source/lang/unimplemented/stringobject.rst @@ -0,0 +1,89 @@ +.. _lang-stringobject: + +String +====== + +Description +----------- + +The String class, part of the core as of version 0019, allows you to +use and manipulate strings of text in more complex ways than character +arrays do. You can concatenate Strings, append to them, search for and +replace substrings, and more. It takes more memory than a simple +character array, but it is also more useful. + + + +For reference, character arrays are referred to as strings with a +small s, and instances of the String class are referred to as +Strings with a capital S. Note that constant strings, specified in +"double quotes" are treated as char arrays, not instances of the +String class. + + + +Functions +--------- + + +- `String <http://arduino.cc/en/Reference/StringConstructor>`_\ () +- `charAt <http://arduino.cc/en/Reference/StringCharAt>`_\ () +- `compareTo <http://arduino.cc/en/Reference/StringCompareTo>`_\ () +- `concat <http://arduino.cc/en/Reference/StringConcat>`_\ () +- `endsWith <http://arduino.cc/en/Reference/StringEndsWith>`_\ () +- `equals <http://arduino.cc/en/Reference/StringEquals>`_\ () +- `equalsIgnoreCase <http://arduino.cc/en/Reference/StringEqualsIgnoreCase>`_\ () +- `getBytes <http://arduino.cc/en/Reference/StringGetBytes>`_\ () +- `indexOf <http://arduino.cc/en/Reference/StringIndexOf>`_\ () +- `lastIndexOf <http://arduino.cc/en/Reference/StringLastIndexOf>`_\ () +- `length <http://arduino.cc/en/Reference/StringLength>`_\ () +- `replace <http://arduino.cc/en/Reference/StringReplace>`_\ () +- `setCharAt <http://arduino.cc/en/Reference/StringSetCharAt>`_\ () +- `startsWith <http://arduino.cc/en/Reference/StringStartsWith>`_\ () +- `substring <http://arduino.cc/en/Reference/StringSubstring>`_\ () +- `toCharArray <http://arduino.cc/en/Reference/StringToCharArray>`_\ () +- `toLowerCase <http://arduino.cc/en/Reference/StringToLowerCase>`_\ () +- `toUpperCase <http://arduino.cc/en/Reference/StringToUpperCase>`_\ () +- `trim <http://arduino.cc/en/Reference/StringTrim>`_\ () + + + +Operators +--------- + + +- `[] (element access) <http://arduino.cc/en/Reference/StringBrackets>`_ +- `+ (concatenation) <http://arduino.cc/en/Reference/StringPlus>`_ +- `== (comparison) <http://arduino.cc/en/Reference/StringComparison>`_ + + + +Examples +-------- + + +- `StringConstructors <http://arduino.cc/en/Tutorial/StringConstructors>`_ +- `StringAdditionOperator <http://arduino.cc/en/Tutorial/StringAdditionOperator>`_ +- `StringIndexOf <http://arduino.cc/en/Tutorial/StringIndexOf>`_ +- `StringAppendOperator <http://arduino.cc/en/Tutorial/StringAppendOperator>`_ +- `StringLengthTrim <http://arduino.cc/en/Tutorial/StringLengthTrim>`_ +- `StringCaseChanges <http://arduino.cc/en/Tutorial/StringCaseChanges>`_ +- `StringReplace <http://arduino.cc/en/Tutorial/StringReplace>`_ +- `StringCharacters <http://arduino.cc/en/Tutorial/StringCharacters>`_ +- `StringStartsWithEndsWith <http://arduino.cc/en/Tutorial/StringStartsWithEndsWith>`_ +- `StringComparisonOperators <http://arduino.cc/en/Tutorial/StringComparisonOperators>`_ +- `StringSubstring <http://arduino.cc/en/Tutorial/StringSubstring>`_ + + + +See Also +-------- + + +- `Character array strings <http://arduino.cc/en/Reference/String>`_ +- `Variable Declaration <http://arduino.cc/en/Reference/VariableDeclaration>`_ + + + + +.. include:: /lang/cc-attribution.txt diff --git a/docs/source/lang/unimplemented/tone.rst b/docs/source/lang/unimplemented/tone.rst new file mode 100644 index 0000000..13d581e --- /dev/null +++ b/docs/source/lang/unimplemented/tone.rst @@ -0,0 +1,58 @@ +.. _lang-tone: + +tone() +====== + +Description +----------- + +Generates a square wave of the specified frequency (and 50% duty +cycle) on a pin. A duration can be specified, otherwise the wave +continues until a call to +`noTone <http://arduino.cc/en/Reference/NoTone>`_\ (). The pin can be +connected to a piezo buzzer or other speaker to play tones. + +Only one tone can be generated at a time. If a tone is already +playing on a different pin, the call to tone() will have no effect. +If the tone is playing on the same pin, the call will set its +frequency. + +Use of the tone() function will interfere with PWM output on pins 3 +and 11 (on boards other than the Mega). + +**NOTE:** if you want to play different pitches on multiple pins, +you need to call noTone() on one pin before calling tone() on the +next pin. + +Syntax +------ + +tone(pin, frequency) +tone(pin, frequency, duration) + +Parameters +---------- + +pin: the pin on which to generate the tone + +frequency: the frequency of the tone in hertz + +duration: the duration of the tone in milliseconds (optional) + +Returns +------- + +nothing + +See Also +-------- + +- `noTone <http://arduino.cc/en/Reference/NoTone>`_\ () +- `analogWrite <http://arduino.cc/en/Reference/AnalogWrite>`_\ () +- `Tutorial:Tone <http://arduino.cc/en/Tutorial/Tone>`_ +- `Tutorial:Pitch follower <http://arduino.cc/en/Tutorial/Tone2>`_ +- `Tutorial:Simple Keyboard <http://arduino.cc/en/Tutorial/Tone3>`_ +- `Tutorial: multiple tones <http://arduino.cc/en/Tutorial/Tone4>`_ +- `Tutorial: PWM <http://arduino.cc/en/Tutorial/PWM>`_ + +.. include:: /arduino-cc-attribution.txt diff --git a/docs/source/language-index.rst b/docs/source/language-index.rst new file mode 100644 index 0000000..5e4c609 --- /dev/null +++ b/docs/source/language-index.rst @@ -0,0 +1,50 @@ +.. _language-index: + +======================= +Complete Language Index +======================= + +This is the index of Maple's :ref:`language reference +<language-lang-docs>` documentation. The "Maple API" column provides +API references for documented libmaple functionality. The "C++ for +Maple" pages are intended as a minimal reference/refresher for +programmers familiar with the Arduino language. + +.. admonition:: **Looking for Something Else?** + + - See the :ref:`libraries` for extra built-in libraries for dealing + with different kinds of hardware. + + - If you're looking for something from the C standard library (like + ``atoi()``, for instance), see :ref:`this FAQ <faq-atoi>`. + + - If you're looking for pointers to low-level details, see the + :ref:`Language Recommended Reading + <language-recommended-reading>` and :ref:`libmaple` pages. + +.. _index-language-index-cpp: +.. _index-language-index-api: + ++----------------------------------+------------------------------------+ +| Maple API | C++ for Maple | +| | | ++==================================+====================================+ +| | | +| .. toctree:: | .. toctree:: | +| :maxdepth: 1 | :maxdepth: 1 | +| :glob: | :glob: | +| | | +| lang/api/* | lang/cpp/* | +| | | ++----------------------------------+------------------------------------+ + +.. Unimplemented or not part of current release: + +.. toctree:: + :hidden: + + lang/unimplemented/tone.rst + lang/unimplemented/notone.rst + lang/unimplemented/pulsein.rst + lang/unimplemented/stringclass.rst + lang/unimplemented/stringobject.rst diff --git a/docs/source/language.rst b/docs/source/language.rst new file mode 100644 index 0000000..a24bb5f --- /dev/null +++ b/docs/source/language.rst @@ -0,0 +1,431 @@ +.. highlight:: c++ + +.. _language: + +==================== + Language Reference +==================== + +The Maple can be programmed in the `Wiring +<http://www.wiring.org.co/reference/>`_ language, which is the same +language used to program the `Arduino <http://arduino.cc/>`_ boards. +C or C++ programmers who are new to Wiring may wish to skip to the +:ref:`arduino_c_for_c_hackers`. + +.. contents:: Contents + :local: + +.. admonition:: Looking for something else? Try these + + - See the :ref:`libraries` for extra built-in libraries. + + - If you prefer C or C++ over Wiring, see :ref:`libmaple` and the + :ref:`unix-toolchain`. + + - If you're looking for something from the C standard library (like + ``atoi()``, for instance), see :ref:`this FAQ <faq-atoi>`. + + - An :ref:`stm32` and other :ref:`language-recommended-reading` are + also available. + +.. _language-lang-docs: + +Maple Language Reference +------------------------ + +This table is a summary of the most important language features. See +the :ref:`language-index` for a complete listing. + ++--------------------------------------------+----------------------------------------------+---------------------------------------------------+ +| Structure | Variables | Functions | +| | | | ++============================================+==============================================+===================================================+ +|* :ref:`setup() <lang-setup>` |**Constants** |**Digital I/O** | +| | | | +|* :ref:`loop() <lang-loop>` |* :ref:`HIGH <lang-constants-high>` | |* :ref:`pinMode() <lang-pinmode>` | +| | :ref:`LOW <lang-constants-low>` | | +| | |* :ref:`digitalWrite() <lang-digitalwrite>` | +|**Control Structures** |* :ref:`INPUT <lang-constants-input>` | | | +| | :ref:`OUTPUT <lang-constants-output>` |* :ref:`digitalRead() <lang-digitalread>` | +|* :ref:`if/else <lang-if>` | | | +| |* :ref:`true <lang-constants-true>` | |* :ref:`togglePin() <lang-togglepin>` | +|* :ref:`for <lang-for>` | :ref:`false <lang-constants-false>` | | +| | |* :ref:`toggleLED() <lang-toggleled>` | +|* :ref:`switch/case <lang-switchcase>` |* :ref:`Constants | | +| | <lang-constants>` (:ref:`integers |* :ref:`isButtonPressed() <lang-isbuttonpressed>` | +|* :ref:`while <lang-while>` | <lang-constants-integers>`, :ref:`floating | | +| | point <lang-constants-fp>`) |* :ref:`waitForButtonPress() | +|* :ref:`do...while <lang-dowhile>` | | <lang-waitforbuttonpress>` | +| |* :ref:`Board-specific values | | +|* :ref:`break <lang-break>` | <lang-board-values>` |**Analog I/O** | +| | | | +|* :ref:`continue <lang-continue>` |**Data Types** |* :ref:`analogRead() <lang-analogread>` | +| | | | +|* :ref:`return <lang-return>` | The size of each data type, in bytes, is |* :ref:`pwmWrite() <lang-pwmwrite>` | +| | given in parentheses where appropriate. | (:ref:`analogWrite() <lang-analogwrite>` is | +|* :ref:`goto <lang-goto>` | | also available, though its use is discouraged) | +| | *Note*: The ``word`` type is (deliberately) | | +| | :ref:`not supported <language-no-word>`. | | +|**Further syntax** | |**Advanced I/O** | +| |* :ref:`void <lang-void>` | | +|* :ref:`; (semicolon) <lang-semicolon>` | |* tone(): TODO | +| |* :ref:`boolean <lang-boolean>` (1 byte) | | +|* :ref:`{} (curly braces) | |* noTone(): TODO | +| <lang-curly-braces>` |* :ref:`char <lang-char>` (1 byte) | | +| | |* :ref:`shiftOut() <lang-shiftout>` | +|* :ref:`// (single-line comment) |* :ref:`unsigned char | | +| <lang-comments-singleline>` | <lang-unsignedchar>` (1 byte) |* pulseIn(): TODO | +| | | | +|* :ref:`/\* \*/ (multi-line comment) |* :ref:`byte <lang-byte>` (1 byte) | | +| <lang-comments-multiline>` | |**Time** | +| |* :ref:`int <lang-int>` (4 bytes) | | +|* :ref:`#define <lang-define>` | |* :ref:`millis() <lang-millis>` | +| |* :ref:`unsigned int <lang-unsignedint>` | | +|* :ref:`#include <lang-include>` | (4 bytes) |* :ref:`micros() <lang-micros>` | +| | | | +| |* ``long`` (4 bytes), synonym for :ref:`int |* :ref:`delay() <lang-delay>` | +|**Arithmetic Operators** | <lang-int>` | | +| | |* :ref:`delayMicroseconds() | +|* :ref:`= <lang-assignment>` |* ``unsigned long`` (4 bytes), synonym for | <lang-delaymicroseconds>` | +| (assignment) | :ref:`unsigned int <lang-unsignedint>` | | +| | | | +|* :ref:`+ <lang-arithmetic>` (addition) |* :ref:`long long <lang-longlong>` (8 bytes) |**Math** | +| | | | +|* :ref:`- <lang-arithmetic>` |* :ref:`unsigned long |* :ref:`min() <lang-min>` | +| (subtraction) | long <lang-unsignedlonglong>` (8 bytes) | | +| | |* :ref:`max() <lang-max>` | +|* :ref:`* <lang-arithmetic>` |* :ref:`float <lang-float>` (4 bytes) | | +| (multiplication) | |* :ref:`abs() <lang-abs>` | +| |* :ref:`double <lang-double>` (8 bytes) | | +|* :ref:`/ <lang-arithmetic>` (division) | |* :ref:`constrain() <lang-constrain>` | +| |* :ref:`strings <lang-string>` | | +|* :ref:`% <lang-modulo>` (modulo) | |* :ref:`map() <lang-map>` | +| |* :ref:`arrays <lang-array>` | | +| | |* :ref:`pow() <lang-pow>` | +|**Comparison Operators** |* :ref:`enum <lang-enum>` | | +| | |* :ref:`sqrt() <lang-sqrt>` | +|* :ref:`== <lang-comparison>` (equal to) |* :ref:`numeric types <lang-built-in-types>` | | +| | | | +|* :ref:`\!= <lang-comparison>` |**Conversion** |**Trigonometry** | +| (not equal to) | | | +| |* :ref:`char() <lang-charcast>` |* :ref:`sin() <lang-sin>` | +|* :ref:`< <lang-comparison>` (less than) | | | +| |* :ref:`byte() <lang-bytecast>` |* :ref:`cos() <lang-cos>` | +|* :ref:`> <lang-comparison>` | | | +| (greater than) |* :ref:`int() <lang-intcast>` |* :ref:`tan() <lang-tan>` | +| | | | +|* :ref:`<= <lang-comparison>` |* :ref:`long() <lang-longcast>` | | +| (less than or equal to) | |**Random Numbers** | +| |* :ref:`float() <lang-floatcast>` | | +|* :ref:`>= <lang-comparison>` | |* :ref:`randomSeed() <lang-randomseed>` | +| (greater than or equal to) |* :ref:`double() <lang-doublecast>` | | +| | |* :ref:`random() <lang-random>` | +| | | | +|**Boolean Operators** |**Variable Scope & Qualifiers** | | +| | |**Bits and Bytes** | +|* :ref:`&& <lang-boolean-and>` (and) |* :ref:`variables <lang-variables>`, | | +| | :ref:`scope <lang-variables-scope>` |* :ref:`lowByte() <lang-lowbyte>` | +|* :ref:`|| <lang-boolean-or>` (or) | | | +| |* :ref:`static <lang-static>` |* :ref:`highByte() <lang-highbyte>` is | +|* :ref:`\! <lang-boolean-not>` (not) | | provided, though its use is discouraged. | +| |* :ref:`volatile <lang-volatile>` | | +| | |* :ref:`bitRead() <lang-bitread>` | +|**Pointer Operators** |* :ref:`const <lang-const>` | | +| | |* :ref:`bitWrite() <lang-bitwrite>` | +|* :ref:`* dereference operator | | | +| <lang-pointer>` |**Utilities** |* :ref:`bitSet() <lang-bitset>` | +| | | | +|* :ref:`& reference operator |* :ref:`sizeof() <lang-sizeof>` |* :ref:`bitClear() <lang-bitclear>` | +| <lang-pointer>` | | | +| |* :ref:`ASSERT() <lang-assert>` |* :ref:`bit() <lang-bit>` | +| | | | +|**Bitwise Operators** | | | +| | |**External Interrupts** | +|* :ref:`& <lang-bitwisemath-and>` | | | +| (bitwise and) | |* :ref:`Reference Page <external-interrupts>` | +| | | | +|* :ref:`| <lang-bitwisemath-or>` | |* :ref:`attachInterrupt() | +| (bitwise or) | | <lang-attachinterrupt>` | +| | | | +|* :ref:`^ <lang-bitwisemath-xor>` | |* :ref:`detachInterrupt() | +| (bitwise xor) | | <lang-detachinterrupt>` | +| | | | +|* :ref:`~ <lang-bitwisemath-not>` | | | +| (bitwise not) | |**Interrupts** | +| | | | +|* :ref:`\<\< <lang-bitshift>` | |* :ref:`interrupts() <lang-interrupts>` | +| (shift left) | | | +| | |* :ref:`noInterrupts() <lang-nointerrupts>` | +|* :ref:`>> <lang-bitshift>` | | | +| (shift right) | | | +| | |**Communication** | +| | | | +|**Compound Operators** | |* :ref:`SerialUSB <lang-serialusb>` | +| | | | +|* :ref:`++ <lang-increment>` | |* :ref:`Serial <lang-serial>` | +| (increment) | | | +| | | | +|* :ref:`- - <lang-increment>` | | | +| (decrement) | | | +| | | | +|* :ref:`+= <lang-compoundarithmetic>` | | | +| (compound add) | | | +| | | | +|* :ref:`-= | | | +| <lang-compoundarithmetic>` (compound | | | +| subtract) | | | +| | | | +|* :ref:`*= | | | +| <lang-compoundarithmetic>` (compound | | | +| multiply) | | | +| | | | +|* :ref:`/= | | | +| <lang-compoundarithmetic>` (compound | | | +| divide) | | | +| | | | +|* :ref:`&= | | | +| <lang-compoundbitwise>` (compound | | | +| bitwise and) | | | +| | | | +|* :ref:`|= | | | +| <lang-compoundbitwise>` (compound | | | +| bitwise or) | | | +| | | | +|**Keywords** | | | +| | | | +|* :ref:`C++ Keywords <lang-keywords>` | | | +| | | | +| | | | ++--------------------------------------------+----------------------------------------------+---------------------------------------------------+ + +.. _language-missing-features: + +Missing Arduino Features +------------------------ + +.. _langage-missing-analogreference: + +**analogReference()** + + It is not possible to implement this function on the Maple + hardware. It will be possible on the upcoming Maple Native. + +.. _language-no-word: + +**word** + + Readers familiar with the Arduino environment may notice that the + ``word`` datatype is missing from the above table's list of data + types. We chose **not to provide** the ``word`` data type on the + Maple. If you want a 16-bit unsigned integer, use the ``uint16`` + type instead. + + While the Maple has 32-bit words, the word size on an Arduino + board is only 16 bits, and code that uses the ``word`` type is + likely to rely on that fact. + + By not supporting ``word``, you'll get a compile error when + porting Arduino code to the Maple instead of potentially weird, + hard-to-debug runtime behavior. + + If you really must have ``word``, you can include the following + ``typedef`` in your program:: + + typedef uint16 word; + +Unimplemented Arduino Features +------------------------------ + +The following Wiring/Arduino features are currently unimplemented on +the Maple. + +- `tone() <http://www.arduino.cc/en/Reference/Tone>`_ +- `noTone() <http://www.arduino.cc/en/Reference/NoTone>`_ +- `pulseIn() <http://www.arduino.cc/en/Reference/PulseIn>`_ +- `String <http://arduino.cc/en/Reference/StringObject>`_ + +.. _our reference page: http://leaflabs.com/docs/external-interrupts/ + +.. _newlib: http://sourceware.org/newlib/ + +.. _cpp-for-maple: + +C++ for Maple +-------------- + +If you haven't programmed in C++, or if you just need to jog your +memory, you may want to check out our :ref:`Language Index +<language-index>`. It provides some introductory coverage of +programming ideas and C++. + +.. _arduino_c_for_c_hackers: + +Note for C/C++ Hackers +---------------------- + +This is a note for programmers comfortable with C or C++ who want a +better understanding of the differences between C++ and the Wiring +language. + +The good news is that the differences are relatively few; Wiring is +just a thin wrapper around C++. Some potentially better news is that +the Maple can be programmed using a :ref:`standard Unix toolchain +<unix-toolchain>`, so if you'd rather stick with :command:`gcc`, +:command:`make`, and friends, you can. If you're using the Unix +toolchain and want to skip past the Wiring conveniences and get +straight to the details, you are encouraged to move on to the +:ref:`libmaple` documentation. + +A *sketch* is the IDE's notion of a project; it consists of one or +more files written in the Wiring language, which is mostly the same as +C++. The major difference between the two is that in Wiring, it's not +necessary to declare global functions before they are used. That is, +the following is valid Wiring, and ``f()`` returns ``5``:: + + int f() { + return g(); + } + + int g() { + return 5; + } + +All of the files in a sketch share the same (global) namespace. That +is, the behavior is as if all of a sketch's files were part of the +same translation unit, so they don't have to include one another in +order to access each other's definitions. + +The Wiring language also does not require you to define your own +``main`` method (in fact, we currently forbid you from doing so). +Instead, you are required to define two functions, ``setup`` and +``loop``, whose prototypes are :: + + void setup(void); + void loop(void); + +Once a sketch is uploaded to a Maple and begins to run, ``setup()`` is +called once, and then ``loop()`` is called repeatedly, forever. The +IDE compilation process proceeds via a source-to-source translation +from the files in a sketch to C++. + +This translation process first concatenates the sketch files, then +parses the result to produce a list of all functions defined in the +global scope. (We borrow this stage from the Arduino IDE, which in +turn borrows it from Wiring. It uses regular expressions to parse +C++, which is, of course, `Bad and Wrong +<http://www.retrologic.com/jargon/B/Bad-and-Wrong.html>`_. In the +future, we'll do this correctly, using a better parser. Until then, +you have our apologies.) The order in which the individual sketch +files are concatenated is not defined; it is unwise to write code that +depends on a particular ordering. + +The concatenated sketch files are then appended onto a file which +includes `WProgram.h +<https://github.com/leaflabs/libmaple/blob/master/wirish/WProgram.h>`_ +(which includes the Wirish and libmaple proper libraries, and declares +``setup()`` and ``loop()``), and then provides declarations for all +the function definitions found in the previous step. At this point, +we have a file that is a valid C++ translation unit, but lacks +``main()``. The final step of compilation provides ``main()``, which +behaves roughly like:: + + int main(void) { + // Call libmaple's built-in initialization routines + init(); + + // Perform the user's initialization + setup(); + + // Call user loop() forever. + while (true) { + loop(); + } + } + +(The truth is a little bit more complicated, but not by much). + +As an example, consider a sketch with two files. The first file +contains ``setup()`` and ``loop()``:: + + int the_pin; + + void setup() { + the_pin = choose_a_pin(); + pinMode(the_pin, OUTPUT); + } + + void loop() { + togglePin(the_pin); + } + +The second file contains the (not very useful) implementation for +``choose_a_pin()``:: + + int choose_a_pin() { + return random(5, 15); + } + +Then the results of the concatenation process might be :: + + int the_pin; + + void setup() { + the_pin = choose_a_pin(); + pinMode(the_pin, OUTPUT); + } + + void loop() { + togglePin(the_pin); + } + + int choose_a_pin(void); + + int choose_a_pin() { + return random(5, 15); + } + +Which could plausibly be turned into the final source file :: + + #include "WProgram.h" + + void setup(void); + void loop(void); + int choose_a_pin(void); + + int the_pin; + + void setup() { + the_pin = choose_a_pin(); + pinMode(the_pin, OUTPUT); + } + + void loop() { + togglePin(the_pin); + } + + int choose_a_pin(void); + + int choose_a_pin() { + return random(5, 15); + } + + int main() { + init(); + setup(); + while (true) loop(); + } + +.. _language-recommended-reading: + +Recommended Reading +------------------- + +* :ref:`Your board's documentation <index-boards>` page, which + includes references to the relevant ST materials (reference manual, + datashseet, etc.) for your board. +* `ARM Cortex-M3 Technical Reference Manual, Revision r1p1 <http://infocenter.arm.com/help/topic/com.arm.doc.ddi0337e/DDI0337E_cortex_m3_r1p1_trm.pdf>`_ + (PDF). This ARM manual specifies the Cortex-M3 architecture, + including instruction timings. +* :ref:`libmaple` +* `newlib's Documentation <http://sourceware.org/newlib/>`_ + (see :ref:`arm-gcc-libc`) diff --git a/docs/source/libmaple.rst b/docs/source/libmaple.rst new file mode 100644 index 0000000..458241e --- /dev/null +++ b/docs/source/libmaple.rst @@ -0,0 +1,48 @@ +.. highlight:: sh + +.. _libmaple: + +``libmaple`` +============ + +LeafLabs' libmaple is the open source library we have developed for +programming the `STM32 <http://www.st.com/stonline>`_ line of +microcontrollers. Libmaple's `source is on GitHub +<https://github.com/leaflabs/libmaple>`_; :ref:`patches are welcome +<libmaple-contributing>`. + +.. _libmaple-vs-wirish: + +Libmaple is split into two pieces: + +- A low-level layer, written in C, called *libmaple proper*, located + in the `libmaple/ + <https://github.com/leaflabs/libmaple/tree/master/libmaple>`_ + subdirectory of the source repository. + +- A high-level layer, written in C++, called *wirish*, in the `wirish/ + <https://github.com/leaflabs/libmaple/tree/master/wirish>`_ + subdirectory. + +Wirish is :ref:`largely compatible <arduino-compatibility>` with the +AVR libraries written for the `Arduino <http://arduino.cc>`_ and +`Wiring <http://wiring.org.co/>`_ development boards. The Wirish +:ref:`language` page is a good summary of what Wirish provides; a +:ref:`complete Wirish API index <language-index>` is also +available. :ref:`Wirish libraries <libraries>` are documented +separately. + +libmaple is bundled with the :ref:`Maple IDE <ide>`. However, we +develop it separately, and :ref:`release it standalone +<unix-toolchain>` for users who might chafe at the "sketch" +programming model of the IDE. The following pages document libmaple +proper. As such, they're intended for advanced users who know how to +write C. + +.. toctree:: + :maxdepth: 1 + + libmaple/overview + libmaple/apis + libmaple/contributing + libmaple/coding-standard diff --git a/docs/source/libmaple/api/adc.rst b/docs/source/libmaple/api/adc.rst new file mode 100644 index 0000000..2f06926 --- /dev/null +++ b/docs/source/libmaple/api/adc.rst @@ -0,0 +1,231 @@ +.. highlight:: c +.. _libmaple-adc: + +``<libmaple/adc.h>`` +==================== + +:ref:`Analog to Digital Conversion <adc>` (ADC) support. + +A common API for basic ADC functionality is available, but the +characteristics of the ADC peripherals vary slightly across +targets. To manage this, each target defines a small set of datatypes +expressing its capabilities (namely :ref:`adc_extsel_event +<adc-adc_extsel_event>`, :ref:`adc_smp_rate <adc-adc_smp_rate>`, and +:ref:`adc_prescaler <adc-adc_prescaler>`). + +.. contents:: Contents + :local: + :depth: 2 + +Devices +------- + +The individual ADC peripherals have the following device struct. + +.. doxygenstruct:: adc_dev + +The available ADC peripherals vary by target. The complete list is +``ADC1``, ``ADC2``, and ``ADC3``. + +.. doxygenvariable:: ADC1 +.. doxygenvariable:: ADC2 +.. doxygenvariable:: ADC3 + +Functions +--------- + +Activation and Deactivation +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +``adc_enable_single_swstart()`` is simple, portable function, which +enables an ADC and sets it up for its basic usage: performing single +conversions using :ref:`adc_read() <adc-adc_read>`. + +.. _adc-adc_enable_single_swstart: +.. doxygenfunction:: adc_enable_single_swstart + +The precise software sequence used varies by target, so this is a good +function to use if your program needs to support multiple MCUs. By +default, Wirish calls ``adc_enable_single_swstart()`` on all available +ADCs at ``init()`` time, so Wirish users don't have to call this +function. + +There are several other lower-level routines used for activating and +deactivating ADCs: + +.. _adc-adc_init: +.. doxygenfunction:: adc_init +.. _adc-adc_enable: +.. doxygenfunction:: adc_enable +.. _adc-adc_disable: +.. doxygenfunction:: adc_disable +.. _adc-adc_disable_all: +.. doxygenfunction:: adc_disable_all + +ADC Conversion +~~~~~~~~~~~~~~ + +``adc_read()`` is a simple function which starts conversion on a +single ADC channel, blocks until it has completed, and returns the +converted result. Don't use the ADC device for any other purpose while +it's running. + +.. _adc-adc_read: +.. doxygenfunction:: adc_read + +To use ``adc_read()``, the device must be configured appropriately. +You can do this with :ref:`adc_enable_single_swstart() +<adc-adc_enable_single_swstart>`. + +Note that for an ADC device to perform conversion on a GPIO input +(which is the usual case; the notable exception being taking +temperature reading), the pin must be configured for analog +conversion. Do this with :ref:`adc_config_gpio() +<adc-adc_config_gpio>`. + +Other routines helpful for ADC conversion: + +.. _adc-adc_set_reg_seqlen: +.. doxygenfunction:: adc_set_reg_seqlen +.. _adc-adc_set_extsel: +.. doxygenfunction:: adc_set_extsel + +.. _adc-adc_extsel_event: + +The last of these, :ref:`adc_set_extsel() <adc-adc_set_extsel>`, takes +a target-dependent ``adc_extsel_event`` argument. + +STM32F1 Targets ++++++++++++++++ + +.. doxygenenum:: stm32f1::adc_extsel_event + +STM32F2 Targets ++++++++++++++++ + +.. doxygenenum:: stm32f2::adc_extsel_event + +ADC Clock Prescaler +~~~~~~~~~~~~~~~~~~~ + +``adc_set_prescaler()`` is available for setting the prescaler which +determines the common ADC clock rate. (Wirish sets a sensible default +for this, so Wirish users ordinarily don't need to call this +function.) + +.. warning:: Increasing the ADC clock rate does speed conversion time, + but the ADC peripherals have a maximum clock rate which must not be + exceeded. Make sure to configure your system and ADC clocks to + respect your device's maximum rate. + +.. _adc_adc_set_prescaler: +.. doxygenfunction:: adc_set_prescaler + +.. _adc-adc_prescaler: + +ADC prescaler values are target-dependent. + +STM32F1 Targets ++++++++++++++++ + +.. doxygenenum:: stm32f1::adc_prescaler + +STM32F2 Targets ++++++++++++++++ + +.. doxygenenum:: stm32f2::adc_prescaler + +.. _adc-adc_set_sample_rate: + +ADC Sample Time +~~~~~~~~~~~~~~~ + +You can control the sampling time (in ADC cycles) for an entire ADC +device using ``adc_set_sample_rate()`` [#fchansamp]_. This function +**only controls the sample rate**; the total conversion time is equal +to the sample time plus an additional number of ADC cycles. Consult +the reference manual for your chip for more details. + +.. warning:: Decreasing ADC sample time speeds conversion, but it also + decreases the maximum allowable impedance of the voltage source you + are measuring. If your voltage source has a high impedance + (e.g. you're measuring Vcc through a potentiometer), and your + sample time is too low, you will get inaccurate results. Consult + the datasheet for your target for more details. + +.. note:: Wirish sets a sensible default sample rate to allow for + high-impedance inputs at ``init()`` time, but Wirish users who know + what they're doing may want to call this function to speed up ADC + conversion. + +.. doxygenfunction:: adc_set_sample_rate + +.. _adc-adc_smp_rate: + +The ``adc_smp_rate`` argument to :ref:`adc_set_sample_rate() +<adc-adc_set_sample_rate>` is target-dependent. + +STM32F1 Targets ++++++++++++++++ + +.. doxygenenum:: stm32f1::adc_smp_rate + +STM32F2 Targets ++++++++++++++++ + +.. doxygenenum:: stm32f2::adc_smp_rate + +Miscellaneous +~~~~~~~~~~~~~ + +.. FIXME [0.0.13] why don't adc_config_gpio()'s docs show up? + +.. _adc-adc_foreach: +.. doxygenfunction:: adc_foreach + +.. _adc-adc_config_gpio: +.. doxygenfunction:: adc_config_gpio + +STM32F1 only +~~~~~~~~~~~~ + +The following routines are available only on STM32F1 targets. + +.. _adc-adc_set_exttrig: +.. doxygenfunction:: adc_set_exttrig + +``adc_calibrate()`` performs calibration necessary on STM32F1 before +using an ADC. Note that on STM32F1 targets, +:ref:`adc_enable_single_swstart() <adc-adc_enable_single_swstart>` +calls ``adc_calibrate()``, so there's no need to do it separately. + +.. _adc-adc_calibrate: +.. doxygenfunction:: adc_calibrate + +Register Maps +------------- + +Individual ADC peripherals have the following register map. The base +pointers are ``ADC1_BASE``, ``ADC2_BASE``, and ``ADC3_BASE``. + +.. _adc-adc_reg_map: +.. doxygenstruct:: adc_reg_map + +On **STM32F2 targets**, there is an additional common set of registers +shared by all ADC peripherals. Its base pointer is +``ADC_COMMON_BASE``. + +.. _adc-adc_common_reg_map: +.. doxygenstruct:: stm32f2::adc_common_reg_map + +Register Bit Definitions +------------------------ + +.. TODO [0.0.13] + +TODO + +.. rubric:: Footnotes + +.. [#fchansamp] Per-channel sample time configuration is possible, + but currently unsupported. diff --git a/docs/source/libmaple/api/bitband.rst b/docs/source/libmaple/api/bitband.rst new file mode 100644 index 0000000..768f678 --- /dev/null +++ b/docs/source/libmaple/api/bitband.rst @@ -0,0 +1,15 @@ +.. highlight:: c +.. _libmaple-bitband: + +``<libmaple/bitband.h>`` +======================== + +Bit-banding support. + +Functions +--------- + +.. doxygenfunction:: bb_sram_get_bit +.. doxygenfunction:: bb_sram_set_bit +.. doxygenfunction:: bb_peri_get_bit +.. doxygenfunction:: bb_peri_set_bit diff --git a/docs/source/libmaple/api/bkp.rst b/docs/source/libmaple/api/bkp.rst new file mode 100644 index 0000000..4f0115b --- /dev/null +++ b/docs/source/libmaple/api/bkp.rst @@ -0,0 +1,79 @@ +.. highlight:: c +.. _libmaple-bkp: + +``bkp.h`` +========= + +Backup register (BKP) suport. + +.. contents:: Contents + :local: + +Types +----- + +.. doxygenstruct:: bkp_dev +.. doxygenstruct:: bkp_reg_map + +Devices +------- + +.. doxygenvariable:: BKP + +Convenience Functions +--------------------- + +.. doxygenfunction:: bkp_init +.. doxygenfunction:: bkp_enable_writes +.. doxygenfunction:: bkp_disable_writes +.. doxygenfunction:: bkp_read +.. doxygenfunction:: bkp_write + +Register Map Base Pointers +-------------------------- + +.. doxygendefine:: BKP_BASE + +Register Bit Definitions +------------------------ + +Data Registers +~~~~~~~~~~~~~~ + +.. doxygendefine:: BKP_DR_D + +RTC Clock Calibration Register +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. doxygendefine:: BKP_RTCCR_ASOS_BIT +.. doxygendefine:: BKP_RTCCR_ASOE_BIT +.. doxygendefine:: BKP_RTCCR_CCO_BIT + +.. doxygendefine:: BKP_RTCCR_ASOS +.. doxygendefine:: BKP_RTCCR_ASOE +.. doxygendefine:: BKP_RTCCR_CCO +.. doxygendefine:: BKP_RTCCR_CAL + +Backup control register +~~~~~~~~~~~~~~~~~~~~~~~ + +.. doxygendefine:: BKP_CR_TPAL_BIT +.. doxygendefine:: BKP_CR_TPE_BIT + +.. doxygendefine:: BKP_CR_TPAL +.. doxygendefine:: BKP_CR_TPE + +Backup control/status register +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. doxygendefine:: BKP_CSR_TIF_BIT +.. doxygendefine:: BKP_CSR_TEF_BIT +.. doxygendefine:: BKP_CSR_TPIE_BIT +.. doxygendefine:: BKP_CSR_CTI_BIT +.. doxygendefine:: BKP_CSR_CTE_BIT + +.. doxygendefine:: BKP_CSR_TIF +.. doxygendefine:: BKP_CSR_TEF +.. doxygendefine:: BKP_CSR_TPIE +.. doxygendefine:: BKP_CSR_CTI +.. doxygendefine:: BKP_CSR_CTE diff --git a/docs/source/libmaple/api/dac.rst b/docs/source/libmaple/api/dac.rst new file mode 100644 index 0000000..55c8faf --- /dev/null +++ b/docs/source/libmaple/api/dac.rst @@ -0,0 +1,123 @@ +.. highlight:: c +.. _libmaple-dac: + +``dac.h`` +========= + +Digital to Analog Conversion (DAC) support. + +.. contents:: Contents + :local: + +Types +----- + +.. doxygenstruct:: dac_dev +.. doxygenstruct:: dac_reg_map + +Devices +------- + +.. doxygenvariable:: DAC + +Functions +--------- + +.. doxygenfunction:: dac_init +.. doxygenfunction:: dac_write_channel +.. doxygenfunction:: dac_enable_channel +.. doxygenfunction:: dac_disable_channel + +Register Map Base Pointers +-------------------------- + +.. doxygendefine:: DAC_BASE + +Register Bit Definitions +------------------------ + +Control register +~~~~~~~~~~~~~~~~ + +**Channel 1**: + +.. doxygendefine:: DAC_CR_EN1 +.. doxygendefine:: DAC_CR_BOFF1 +.. doxygendefine:: DAC_CR_TEN1 +.. doxygendefine:: DAC_CR_TSEL1 +.. doxygendefine:: DAC_CR_WAVE1 +.. doxygendefine:: DAC_CR_MAMP1 +.. doxygendefine:: DAC_CR_DMAEN1 + +**Channel 2**: + +.. doxygendefine:: DAC_CR_EN2 +.. doxygendefine:: DAC_CR_BOFF2 +.. doxygendefine:: DAC_CR_TEN2 +.. doxygendefine:: DAC_CR_TSEL2 +.. doxygendefine:: DAC_CR_WAVE2 +.. doxygendefine:: DAC_CR_MAMP2 +.. doxygendefine:: DAC_CR_DMAEN2 + +Software trigger register +~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. doxygendefine:: DAC_SWTRIGR_SWTRIG1 +.. doxygendefine:: DAC_SWTRIGR_SWTRIG2 + +Channel 1 12-bit right-aligned data holding register +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. doxygendefine:: DAC_DHR12R1_DACC1DHR + +Channel 1 12-bit left-aligned data holding register +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. doxygendefine:: DAC_DHR12L1_DACC1DHR + +Channel 1 8-bit left-aligned data holding register +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. doxygendefine:: DAC_DHR8R1_DACC1DHR + +Channel 2 12-bit right-aligned data holding register +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. doxygendefine:: DAC_DHR12R2_DACC2DHR + +Channel 2 12-bit left-aligned data holding register +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. doxygendefine:: DAC_DHR12L2_DACC2DHR + +Channel 2 8-bit left-aligned data holding register +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. doxygendefine:: DAC_DHR8R2_DACC2DHR + +Dual DAC 12-bit right-aligned data holding register +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. doxygendefine:: DAC_DHR12RD_DACC1DHR +.. doxygendefine:: DAC_DHR12RD_DACC2DHR + +Dual DAC 12-bit left-aligned data holding register +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. doxygendefine:: DAC_DHR12LD_DACC1DHR +.. doxygendefine:: DAC_DHR12LD_DACC2DHR + +Dual DAC 8-bit left-aligned data holding register +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. doxygendefine:: DAC_DHR8RD_DACC1DHR +.. doxygendefine:: DAC_DHR8RD_DACC2DHR + +Channel 1 data output register +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. doxygendefine:: DAC_DOR1_DACC1DOR + +Channel 1 data output register +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.. doxygendefine:: DAC_DOR2_DACC2DOR diff --git a/docs/source/libmaple/api/delay.rst b/docs/source/libmaple/api/delay.rst new file mode 100644 index 0000000..d11496b --- /dev/null +++ b/docs/source/libmaple/api/delay.rst @@ -0,0 +1,11 @@ +.. highlight:: c +.. _libmaple-delay: + +``<libmaple/delay.h>`` +====================== + +Provides a simple busy-loop delay function. Note that this function +does not account for time spent in interrupts, so actual delay times +may vary depending on your application. + +.. doxygenfunction:: delay_us diff --git a/docs/source/libmaple/api/dma.rst b/docs/source/libmaple/api/dma.rst new file mode 100644 index 0000000..a9893e2 --- /dev/null +++ b/docs/source/libmaple/api/dma.rst @@ -0,0 +1,215 @@ +.. highlight:: c +.. _libmaple-dma: + +``dma.h`` +========= + +Direct Memory Access (DMA) support. + +.. contents:: Contents + :local: + +Types +----- + +.. doxygenstruct:: dma_reg_map +.. doxygenstruct:: dma_dev +.. doxygenstruct:: dma_handler_config +.. doxygenenum:: dma_mode_flags +.. doxygenenum:: dma_xfer_size +.. doxygenenum:: dma_channel +.. doxygenenum:: dma_priority +.. doxygenenum:: dma_irq_cause +.. doxygenstruct:: dma_channel_reg_map + +Devices +------- + +.. doxygenvariable:: DMA1 +.. doxygenvariable:: DMA2 + +Functions +--------- + +.. doxygenfunction:: dma_init +.. doxygenfunction:: dma_setup_transfer +.. doxygenfunction:: dma_set_num_transfers +.. doxygenfunction:: dma_set_priority +.. doxygenfunction:: dma_attach_interrupt +.. doxygenfunction:: dma_detach_interrupt +.. doxygenfunction:: dma_get_irq_cause +.. doxygenfunction:: dma_enable +.. doxygenfunction:: dma_disable +.. doxygenfunction:: dma_set_mem_addr +.. doxygenfunction:: dma_set_per_addr +.. doxygenfunction:: dma_channel_regs +.. doxygenfunction:: dma_is_channel_enabled +.. doxygenfunction:: dma_get_isr_bits +.. doxygenfunction:: dma_clear_isr_bits + +Register Map Base Pointers +-------------------------- + +.. doxygendefine:: DMA1_BASE +.. doxygendefine:: DMA2_BASE + +Register Bit Definitions +------------------------ + +Interrupt status register +~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. doxygendefine:: DMA_ISR_TEIF7_BIT +.. doxygendefine:: DMA_ISR_HTIF7_BIT +.. doxygendefine:: DMA_ISR_TCIF7_BIT +.. doxygendefine:: DMA_ISR_GIF7_BIT +.. doxygendefine:: DMA_ISR_TEIF6_BIT +.. doxygendefine:: DMA_ISR_HTIF6_BIT +.. doxygendefine:: DMA_ISR_TCIF6_BIT +.. doxygendefine:: DMA_ISR_GIF6_BIT +.. doxygendefine:: DMA_ISR_TEIF5_BIT +.. doxygendefine:: DMA_ISR_HTIF5_BIT +.. doxygendefine:: DMA_ISR_TCIF5_BIT +.. doxygendefine:: DMA_ISR_GIF5_BIT +.. doxygendefine:: DMA_ISR_TEIF4_BIT +.. doxygendefine:: DMA_ISR_HTIF4_BIT +.. doxygendefine:: DMA_ISR_TCIF4_BIT +.. doxygendefine:: DMA_ISR_GIF4_BIT +.. doxygendefine:: DMA_ISR_TEIF3_BIT +.. doxygendefine:: DMA_ISR_HTIF3_BIT +.. doxygendefine:: DMA_ISR_TCIF3_BIT +.. doxygendefine:: DMA_ISR_GIF3_BIT +.. doxygendefine:: DMA_ISR_TEIF2_BIT +.. doxygendefine:: DMA_ISR_HTIF2_BIT +.. doxygendefine:: DMA_ISR_TCIF2_BIT +.. doxygendefine:: DMA_ISR_GIF2_BIT +.. doxygendefine:: DMA_ISR_TEIF1_BIT +.. doxygendefine:: DMA_ISR_HTIF1_BIT +.. doxygendefine:: DMA_ISR_TCIF1_BIT +.. doxygendefine:: DMA_ISR_GIF1_BIT + +.. doxygendefine:: DMA_ISR_TEIF7 +.. doxygendefine:: DMA_ISR_HTIF7 +.. doxygendefine:: DMA_ISR_TCIF7 +.. doxygendefine:: DMA_ISR_GIF7 +.. doxygendefine:: DMA_ISR_TEIF6 +.. doxygendefine:: DMA_ISR_HTIF6 +.. doxygendefine:: DMA_ISR_TCIF6 +.. doxygendefine:: DMA_ISR_GIF6 +.. doxygendefine:: DMA_ISR_TEIF5 +.. doxygendefine:: DMA_ISR_HTIF5 +.. doxygendefine:: DMA_ISR_TCIF5 +.. doxygendefine:: DMA_ISR_GIF5 +.. doxygendefine:: DMA_ISR_TEIF4 +.. doxygendefine:: DMA_ISR_HTIF4 +.. doxygendefine:: DMA_ISR_TCIF4 +.. doxygendefine:: DMA_ISR_GIF4 +.. doxygendefine:: DMA_ISR_TEIF3 +.. doxygendefine:: DMA_ISR_HTIF3 +.. doxygendefine:: DMA_ISR_TCIF3 +.. doxygendefine:: DMA_ISR_GIF3 +.. doxygendefine:: DMA_ISR_TEIF2 +.. doxygendefine:: DMA_ISR_HTIF2 +.. doxygendefine:: DMA_ISR_TCIF2 +.. doxygendefine:: DMA_ISR_GIF2 +.. doxygendefine:: DMA_ISR_TEIF1 +.. doxygendefine:: DMA_ISR_HTIF1 +.. doxygendefine:: DMA_ISR_TCIF1 +.. doxygendefine:: DMA_ISR_GIF1 + +Interrupt flag clear register +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. doxygendefine:: DMA_IFCR_CTEIF7_BIT +.. doxygendefine:: DMA_IFCR_CHTIF7_BIT +.. doxygendefine:: DMA_IFCR_CTCIF7_BIT +.. doxygendefine:: DMA_IFCR_CGIF7_BIT +.. doxygendefine:: DMA_IFCR_CTEIF6_BIT +.. doxygendefine:: DMA_IFCR_CHTIF6_BIT +.. doxygendefine:: DMA_IFCR_CTCIF6_BIT +.. doxygendefine:: DMA_IFCR_CGIF6_BIT +.. doxygendefine:: DMA_IFCR_CTEIF5_BIT +.. doxygendefine:: DMA_IFCR_CHTIF5_BIT +.. doxygendefine:: DMA_IFCR_CTCIF5_BIT +.. doxygendefine:: DMA_IFCR_CGIF5_BIT +.. doxygendefine:: DMA_IFCR_CTEIF4_BIT +.. doxygendefine:: DMA_IFCR_CHTIF4_BIT +.. doxygendefine:: DMA_IFCR_CTCIF4_BIT +.. doxygendefine:: DMA_IFCR_CGIF4_BIT +.. doxygendefine:: DMA_IFCR_CTEIF3_BIT +.. doxygendefine:: DMA_IFCR_CHTIF3_BIT +.. doxygendefine:: DMA_IFCR_CTCIF3_BIT +.. doxygendefine:: DMA_IFCR_CGIF3_BIT +.. doxygendefine:: DMA_IFCR_CTEIF2_BIT +.. doxygendefine:: DMA_IFCR_CHTIF2_BIT +.. doxygendefine:: DMA_IFCR_CTCIF2_BIT +.. doxygendefine:: DMA_IFCR_CGIF2_BIT +.. doxygendefine:: DMA_IFCR_CTEIF1_BIT +.. doxygendefine:: DMA_IFCR_CHTIF1_BIT +.. doxygendefine:: DMA_IFCR_CTCIF1_BIT +.. doxygendefine:: DMA_IFCR_CGIF1_BIT + +.. doxygendefine:: DMA_IFCR_CTEIF7 +.. doxygendefine:: DMA_IFCR_CHTIF7 +.. doxygendefine:: DMA_IFCR_CTCIF7 +.. doxygendefine:: DMA_IFCR_CGIF7 +.. doxygendefine:: DMA_IFCR_CTEIF6 +.. doxygendefine:: DMA_IFCR_CHTIF6 +.. doxygendefine:: DMA_IFCR_CTCIF6 +.. doxygendefine:: DMA_IFCR_CGIF6 +.. doxygendefine:: DMA_IFCR_CTEIF5 +.. doxygendefine:: DMA_IFCR_CHTIF5 +.. doxygendefine:: DMA_IFCR_CTCIF5 +.. doxygendefine:: DMA_IFCR_CGIF5 +.. doxygendefine:: DMA_IFCR_CTEIF4 +.. doxygendefine:: DMA_IFCR_CHTIF4 +.. doxygendefine:: DMA_IFCR_CTCIF4 +.. doxygendefine:: DMA_IFCR_CGIF4 +.. doxygendefine:: DMA_IFCR_CTEIF3 +.. doxygendefine:: DMA_IFCR_CHTIF3 +.. doxygendefine:: DMA_IFCR_CTCIF3 +.. doxygendefine:: DMA_IFCR_CGIF3 +.. doxygendefine:: DMA_IFCR_CTEIF2 +.. doxygendefine:: DMA_IFCR_CHTIF2 +.. doxygendefine:: DMA_IFCR_CTCIF2 +.. doxygendefine:: DMA_IFCR_CGIF2 +.. doxygendefine:: DMA_IFCR_CTEIF1 +.. doxygendefine:: DMA_IFCR_CHTIF1 +.. doxygendefine:: DMA_IFCR_CTCIF1 +.. doxygendefine:: DMA_IFCR_CGIF1 + +Channel configuration register +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. doxygendefine:: DMA_CCR_MEM2MEM_BIT +.. doxygendefine:: DMA_CCR_MINC_BIT +.. doxygendefine:: DMA_CCR_PINC_BIT +.. doxygendefine:: DMA_CCR_CIRC_BIT +.. doxygendefine:: DMA_CCR_DIR_BIT +.. doxygendefine:: DMA_CCR_TEIE_BIT +.. doxygendefine:: DMA_CCR_HTIE_BIT +.. doxygendefine:: DMA_CCR_TCIE_BIT +.. doxygendefine:: DMA_CCR_EN_BIT + +.. doxygendefine:: DMA_CCR_MEM2MEM +.. doxygendefine:: DMA_CCR_PL +.. doxygendefine:: DMA_CCR_PL_LOW +.. doxygendefine:: DMA_CCR_PL_MEDIUM +.. doxygendefine:: DMA_CCR_PL_HIGH +.. doxygendefine:: DMA_CCR_PL_VERY_HIGH +.. doxygendefine:: DMA_CCR_MSIZE +.. doxygendefine:: DMA_CCR_MSIZE_8BITS +.. doxygendefine:: DMA_CCR_MSIZE_16BITS +.. doxygendefine:: DMA_CCR_MSIZE_32BITS +.. doxygendefine:: DMA_CCR_PSIZE +.. doxygendefine:: DMA_CCR_PSIZE_8BITS +.. doxygendefine:: DMA_CCR_PSIZE_16BITS +.. doxygendefine:: DMA_CCR_PSIZE_32BITS +.. doxygendefine:: DMA_CCR_MINC +.. doxygendefine:: DMA_CCR_PINC +.. doxygendefine:: DMA_CCR_CIRC +.. doxygendefine:: DMA_CCR_DIR +.. doxygendefine:: DMA_CCR_TEIE +.. doxygendefine:: DMA_CCR_HTIE +.. doxygendefine:: DMA_CCR_TCIE +.. doxygendefine:: DMA_CCR_EN diff --git a/docs/source/libmaple/api/exti.rst b/docs/source/libmaple/api/exti.rst new file mode 100644 index 0000000..1038fbf --- /dev/null +++ b/docs/source/libmaple/api/exti.rst @@ -0,0 +1,37 @@ +.. highlight:: c +.. _libmaple-exti: + +``exti.h`` +========== + +:ref:`External interrupt <external-interrupts>` support. + +.. contents:: Contents + :local: + +Types +----- + +.. doxygenstruct:: exti_reg_map +.. doxygenenum:: exti_trigger_mode + +Devices +------- + +None at this time. + +Functions +--------- + +.. doxygenfunction:: exti_attach_interrupt +.. doxygenfunction:: exti_detach_interrupt + +Register Map Base Pointers +-------------------------- + +.. doxygendefine:: EXTI_BASE + +Register Bit Definitions +------------------------ + +None at this time. diff --git a/docs/source/libmaple/api/flash.rst b/docs/source/libmaple/api/flash.rst new file mode 100644 index 0000000..52ff4d2 --- /dev/null +++ b/docs/source/libmaple/api/flash.rst @@ -0,0 +1,249 @@ +.. highlight:: c +.. _libmaple-flash: + +``<libmaple/flash.h>`` +====================== + +Flash memory support. + +The built-in Flash on different STM32 MCUs varies in terms of its +eraseable page/sector size and read/write protections. There isn't +currently much support for dealing with this. This header is mostly +useful for its functions that control Flash features which affect +system performance, like wait states and prefetch buffers. + +.. contents:: Contents + :local: + +Devices +------- + +None at this time. + +Functions +--------- + +The following functions can be used to portably manipulate Flash memory. + +.. doxygenfunction:: flash_set_latency +.. doxygenfunction:: flash_enable_features +.. doxygenfunction:: flash_enable_prefetch + +Register Maps +------------- + +Register maps vary by target. The base pointer is always ``FLASH_BASE``. + +Base Pointer +~~~~~~~~~~~~ + +.. doxygendefine:: FLASH_BASE + +STM32F1 targets +~~~~~~~~~~~~~~~ + +.. doxygenstruct:: stm32f1::flash_reg_map + +STM32F2 targets +~~~~~~~~~~~~~~~ + +.. doxygenstruct:: stm32f2::flash_reg_map + +Register Bit Definitions +------------------------ + +These are given as source code. Available register bit definitions +vary by target. + +STM32F1 Targets +~~~~~~~~~~~~~~~ + +:: + + /* Access control register */ + + #define FLASH_ACR_PRFTBS_BIT 5 + #define FLASH_ACR_PRFTBE_BIT 4 + #define FLASH_ACR_HLFCYA_BIT 3 + + #define FLASH_ACR_PRFTBS (1U << FLASH_ACR_PRFTBS_BIT) + #define FLASH_ACR_PRFTBE (1U << FLASH_ACR_PRFTBE_BIT) + #define FLASH_ACR_HLFCYA (1U << FLASH_ACR_HLFCYA_BIT) + #define FLASH_ACR_LATENCY 0x7 + + /* Status register */ + + #define FLASH_SR_EOP_BIT 5 + #define FLASH_SR_WRPRTERR_BIT 4 + #define FLASH_SR_PGERR_BIT 2 + #define FLASH_SR_BSY_BIT 0 + + #define FLASH_SR_EOP (1U << FLASH_SR_EOP_BIT) + #define FLASH_SR_WRPRTERR (1U << FLASH_SR_WRPRTERR_BIT) + #define FLASH_SR_PGERR (1U << FLASH_SR_PGERR_BIT) + #define FLASH_SR_BSY (1U << FLASH_SR_BSY_BIT) + + /* Control register */ + + #define FLASH_CR_EOPIE_BIT 12 + #define FLASH_CR_ERRIE_BIT 10 + #define FLASH_CR_OPTWRE_BIT 9 + #define FLASH_CR_LOCK_BIT 7 + #define FLASH_CR_STRT_BIT 6 + #define FLASH_CR_OPTER_BIT 5 + #define FLASH_CR_OPTPG_BIT 4 + #define FLASH_CR_MER_BIT 2 + #define FLASH_CR_PER_BIT 1 + #define FLASH_CR_PG_BIT 0 + + #define FLASH_CR_EOPIE (1U << FLASH_CR_EOPIE_BIT) + #define FLASH_CR_ERRIE (1U << FLASH_CR_ERRIE_BIT) + #define FLASH_CR_OPTWRE (1U << FLASH_CR_OPTWRE_BIT) + #define FLASH_CR_LOCK (1U << FLASH_CR_LOCK_BIT) + #define FLASH_CR_STRT (1U << FLASH_CR_STRT_BIT) + #define FLASH_CR_OPTER (1U << FLASH_CR_OPTER_BIT) + #define FLASH_CR_OPTPG (1U << FLASH_CR_OPTPG_BIT) + #define FLASH_CR_MER (1U << FLASH_CR_MER_BIT) + #define FLASH_CR_PER (1U << FLASH_CR_PER_BIT) + #define FLASH_CR_PG (1U << FLASH_CR_PG_BIT) + + /* Option byte register */ + + #define FLASH_OBR_nRST_STDBY_BIT 4 + #define FLASH_OBR_nRST_STOP_BIT 3 + #define FLASH_OBR_WDG_SW_BIT 2 + #define FLASH_OBR_RDPRT_BIT 1 + #define FLASH_OBR_OPTERR_BIT 0 + + #define FLASH_OBR_DATA1 (0xFF << 18) + #define FLASH_OBR_DATA0 (0xFF << 10) + #define FLASH_OBR_USER 0x3FF + #define FLASH_OBR_nRST_STDBY (1U << FLASH_OBR_nRST_STDBY_BIT) + #define FLASH_OBR_nRST_STOP (1U << FLASH_OBR_nRST_STOP_BIT) + #define FLASH_OBR_WDG_SW (1U << FLASH_OBR_WDG_SW_BIT) + #define FLASH_OBR_RDPRT (1U << FLASH_OBR_RDPRT_BIT) + #define FLASH_OBR_OPTERR (1U << FLASH_OBR_OPTERR_BIT) + +STM32F2 Targets +~~~~~~~~~~~~~~~ + +:: + + /* Access control register */ + + #define FLASH_ACR_DCRST_BIT 12 + #define FLASH_ACR_ICRST_BIT 11 + #define FLASH_ACR_DCEN_BIT 10 + #define FLASH_ACR_ICEN_BIT 9 + #define FLASH_ACR_PRFTEN_BIT 8 + + #define FLASH_ACR_DCRST (1U << FLASH_ACR_DCRST_BIT) + #define FLASH_ACR_ICRST (1U << FLASH_ACR_ICRST_BIT) + #define FLASH_ACR_DCEN (1U << FLASH_ACR_DCEN_BIT) + #define FLASH_ACR_ICEN (1U << FLASH_ACR_ICEN_BIT) + #define FLASH_ACR_PRFTEN (1U << FLASH_ACR_PRFTEN_BIT) + #define FLASH_ACR_LATENCY 0x7 + #define FLASH_ACR_LATENCY_0WS 0x0 + #define FLASH_ACR_LATENCY_1WS 0x1 + #define FLASH_ACR_LATENCY_2WS 0x2 + #define FLASH_ACR_LATENCY_3WS 0x3 + #define FLASH_ACR_LATENCY_4WS 0x4 + #define FLASH_ACR_LATENCY_5WS 0x5 + #define FLASH_ACR_LATENCY_6WS 0x6 + #define FLASH_ACR_LATENCY_7WS 0x7 + + /* Key register */ + + #define FLASH_KEYR_KEY1 0x45670123 + #define FLASH_KEYR_KEY2 0xCDEF89AB + + /* Option key register */ + + #define FLASH_OPTKEYR_OPTKEY1 0x08192A3B + #define FLASH_OPTKEYR_OPTKEY2 0x4C5D6E7F + + /* Status register */ + + #define FLASH_SR_BSY_BIT 16 + #define FLASH_SR_PGSERR_BIT 7 + #define FLASH_SR_PGPERR_BIT 6 + #define FLASH_SR_PGAERR_BIT 5 + #define FLASH_SR_WRPERR_BIT 4 + #define FLASH_SR_OPERR_BIT 1 + #define FLASH_SR_EOP_BIT 0 + + #define FLASH_SR_BSY (1U << FLASH_SR_BSY_BIT) + #define FLASH_SR_PGSERR (1U << FLASH_SR_PGSERR_BIT) + #define FLASH_SR_PGPERR (1U << FLASH_SR_PGPERR_BIT) + #define FLASH_SR_PGAERR (1U << FLASH_SR_PGAERR_BIT) + #define FLASH_SR_WRPERR (1U << FLASH_SR_WRPERR_BIT) + #define FLASH_SR_OPERR (1U << FLASH_SR_OPERR_BIT) + #define FLASH_SR_EOP (1U << FLASH_SR_EOP_BIT) + + /* Control register */ + + #define FLASH_CR_LOCK_BIT 31 + #define FLASH_CR_ERRIE_BIT 25 + #define FLASH_CR_EOPIE_BIT 24 + #define FLASH_CR_STRT_BIT 16 + #define FLASH_CR_MER_BIT 2 + #define FLASH_CR_SER_BIT 1 + #define FLASH_CR_PG_BIT 0 + + #define FLASH_CR_LOCK (1U << FLASH_CR_LOCK_BIT) + #define FLASH_CR_ERRIE (1U << FLASH_CR_ERRIE_BIT) + #define FLASH_CR_EOPIE (1U << FLASH_CR_EOPIE_BIT) + #define FLASH_CR_STRT (1U << FLASH_CR_STRT_BIT) + + #define FLASH_CR_PSIZE (0x3 << 8) + #define FLASH_CR_PSIZE_MUL8 (0x0 << 8) + #define FLASH_CR_PSIZE_MUL16 (0x1 << 8) + #define FLASH_CR_PSIZE_MUL32 (0x2 << 8) + #define FLASH_CR_PSIZE_MUL64 (0x3 << 8) + + #define FLASH_CR_SNB (0xF << 3) + #define FLASH_CR_SNB_0 (0x0 << 3) + #define FLASH_CR_SNB_1 (0x1 << 3) + #define FLASH_CR_SNB_2 (0x2 << 3) + #define FLASH_CR_SNB_3 (0x3 << 3) + #define FLASH_CR_SNB_4 (0x4 << 3) + #define FLASH_CR_SNB_5 (0x5 << 3) + #define FLASH_CR_SNB_6 (0x6 << 3) + #define FLASH_CR_SNB_7 (0x7 << 3) + #define FLASH_CR_SNB_8 (0x8 << 3) + #define FLASH_CR_SNB_9 (0x9 << 3) + #define FLASH_CR_SNB_10 (0xA << 3) + #define FLASH_CR_SNB_11 (0xB << 3) + + #define FLASH_CR_MER (1U << FLASH_CR_MER_BIT) + #define FLASH_CR_SER (1U << FLASH_CR_SER_BIT) + #define FLASH_CR_PG (1U << FLASH_CR_PG_BIT) + + /* Option control register */ + + #define FLASH_OPTCR_NRST_STDBY_BIT 7 + #define FLASH_OPTCR_NRST_STOP_BIT 6 + #define FLASH_OPTCR_WDG_SW_BIT 5 + #define FLASH_OPTCR_OPTSTRT_BIT 1 + #define FLASH_OPTCR_OPTLOCK_BIT 0 + + #define FLASH_OPTCR_NWRP (0x3FF << 16) + + /* Excluded: The many level 1 values */ + #define FLASH_OPTCR_RDP (0xFF << 8) + #define FLASH_OPTCR_RDP_LEVEL0 (0xAA << 8) + #define FLASH_OPTCR_RDP_LEVEL2 (0xCC << 8) + + #define FLASH_OPTCR_USER (0x7 << 5) + #define FLASH_OPTCR_nRST_STDBY (1U << FLASH_OPTCR_nRST_STDBY_BIT) + #define FLASH_OPTCR_nRST_STOP (1U << FLASH_OPTCR_nRST_STOP_BIT) + #define FLASH_OPTCR_WDG_SW (1U << FLASH_OPTCR_WDG_SW_BIT) + + #define FLASH_OPTCR_BOR_LEV (0x3 << 2) + #define FLASH_OPTCR_BOR_LEVEL3 (0x0 << 2) + #define FLASH_OPTCR_BOR_LEVEL2 (0x1 << 2) + #define FLASH_OPTCR_BOR_LEVEL1 (0x2 << 2) + #define FLASH_OPTCR_BOR_OFF (0x3 << 2) + + #define FLASH_OPTCR_OPTSTRT (1U << FLASH_OPTCR_OPTSTRT_BIT) + #define FLASH_OPTCR_OPTLOCK (1U << FLASH_OPTCR_OPTLOCK_BIT) diff --git a/docs/source/libmaple/api/fsmc.rst b/docs/source/libmaple/api/fsmc.rst new file mode 100644 index 0000000..e2bf87a --- /dev/null +++ b/docs/source/libmaple/api/fsmc.rst @@ -0,0 +1,235 @@ +.. highlight:: c +.. _libmaple-fsmc: + +``<libmaple/fsmc.h>`` +===================== + +Flexible Static Memory Controller (FSMC) support. The FSMC peripheral +is only available on some targets. Including this header on a target +without an FSMC will cause a compilation error. Check your target's +documentation to determine if it's available. You can also use +:ref:`STM32_HAVE_FSMC <libmaple-stm32-STM32_HAVE_FSMC>` from +``<libmaple/stm32.h>`` to determine whether your target has an FSMC at +build time. + +All functionality documented here is portable. + +.. contents:: Contents + :local: + +Usage Note +---------- + +FSMC support is fairly limited at this time. Current Leaflabs boards +only use the FSMC to interface with external SRAM chips, so that's +what there's the most support for (:ref:`patches welcome! +<libmaple-contributing>`). Even for use with SRAM, you will still need +to program some registers directly. + +To use the FSMC with an SRAM chip, first call +:ref:`fsmc_sram_init_gpios() <libmaple-fsmc-fsmc_sram_init_gpios>` to +configure its data, address, and control lines. Then, turn on the +FSMC clock (by calling :ref:`rcc_clk_enable(RCC_FSMC) +<libmaple-rcc-rcc_clk_enable>`). You can then configure the relevant +:ref:`fsmc_nor_psram_reg_map <libmaple-fsmc-fsmc_nor_psram_reg_map>` +``BCR`` register yourself for the SRAM chip you are using. + +You can additionally use :ref:`fsmc_nor_psram_set_datast() +<libmaple-fsmc-fsmc_nor_psram_set_datast>` and +:ref:`fsmc_nor_psram_set_datast() <libmaple-fsmc-fsmc_nor_psram_set_datast>` +to control read/write timing. + +Devices +------- + +None at this time. + +Functions +--------- + +.. _libmaple-fsmc-fsmc_sram_init_gpios: +.. doxygenfunction:: fsmc_sram_init_gpios +.. _libmaple-fsmc-fsmc_nor_psram_set_datast: +.. doxygenfunction:: fsmc_nor_psram_set_datast +.. _libmaple-fsmc-fsmc_nor_psram_set_addset: +.. doxygenfunction:: fsmc_nor_psram_set_addset + +Register Maps +------------- + +The general purpose register map type is ``fsmc_reg_map``; its base +pointer is ``FSMC_BASE``. The ``fsmc_nor_psram_reg_map`` type is for +use configuring the registers for an individual NOR/PSRAM region +(``FSMC_BCRx``, ``FSMC_BTRx``, and ``FSMC_BWTRx``); the relevant base +pointers are ``FSMC_NOR_PSRAM_REGION1`` through +``FSMC_NOR_PSRAM_REGION4``. + +.. doxygendefine:: FSMC_BASE + +.. doxygendefine:: FSMC_NOR_PSRAM1_BASE +.. doxygendefine:: FSMC_NOR_PSRAM2_BASE +.. doxygendefine:: FSMC_NOR_PSRAM3_BASE +.. doxygendefine:: FSMC_NOR_PSRAM4_BASE + +.. doxygenstruct:: fsmc_reg_map +.. _libmaple-fsmc-fsmc_nor_psram_reg_map: +.. doxygenstruct:: fsmc_nor_psram_reg_map + +Memory Bank Boundary Addresses +------------------------------ + +Reading and writing data on an external memory chip using FSMC is done +by reading and writing from addresses in special memory-mapped +sections of the address space called *memory banks*. + +This is convenient, since it implies that the usual load and store +instructions used for I/O with the internal SRAM are also used to +perform bus transactions with the external memory chip. (Which means +you can use ``memcpy()`` etc. on external memory.) + +Pointers to the memory banks' base addresses are given by the +following macros. + +.. doxygendefine:: FSMC_BANK1 +.. doxygendefine:: FSMC_BANK2 +.. doxygendefine:: FSMC_BANK3 +.. doxygendefine:: FSMC_BANK4 + +.. doxygendefine:: FSMC_NOR_PSRAM_REGION1 +.. doxygendefine:: FSMC_NOR_PSRAM_REGION2 +.. doxygendefine:: FSMC_NOR_PSRAM_REGION3 +.. doxygendefine:: FSMC_NOR_PSRAM_REGION4 + +Register Bit Definitions +------------------------ + +These are given as source code. + +:: + + /* NOR/PSRAM chip-select control registers */ + + #define FSMC_BCR_CBURSTRW_BIT 19 + #define FSMC_BCR_ASYNCWAIT_BIT 15 + #define FSMC_BCR_EXTMOD_BIT 14 + #define FSMC_BCR_WAITEN_BIT 13 + #define FSMC_BCR_WREN_BIT 12 + #define FSMC_BCR_WAITCFG_BIT 11 + #define FSMC_BCR_WRAPMOD_BIT 10 + #define FSMC_BCR_WAITPOL_BIT 9 + #define FSMC_BCR_BURSTEN_BIT 8 + #define FSMC_BCR_FACCEN_BIT 6 + #define FSMC_BCR_MUXEN_BIT 1 + #define FSMC_BCR_MBKEN_BIT 0 + + #define FSMC_BCR_CBURSTRW (1U << FSMC_BCR_CBURSTRW_BIT) + #define FSMC_BCR_ASYNCWAIT (1U << FSMC_BCR_ASYNCWAIT_BIT) + #define FSMC_BCR_EXTMOD (1U << FSMC_BCR_EXTMOD_BIT) + #define FSMC_BCR_WAITEN (1U << FSMC_BCR_WAITEN_BIT) + #define FSMC_BCR_WREN (1U << FSMC_BCR_WREN_BIT) + #define FSMC_BCR_WAITCFG (1U << FSMC_BCR_WAITCFG_BIT) + #define FSMC_BCR_WRAPMOD (1U << FSMC_BCR_WRAPMOD_BIT) + #define FSMC_BCR_WAITPOL (1U << FSMC_BCR_WAITPOL_BIT) + #define FSMC_BCR_BURSTEN (1U << FSMC_BCR_BURSTEN_BIT) + #define FSMC_BCR_FACCEN (1U << FSMC_BCR_FACCEN_BIT) + #define FSMC_BCR_MWID (0x3 << 4) + #define FSMC_BCR_MWID_8BITS (0x0 << 4) + #define FSMC_BCR_MWID_16BITS (0x1 << 4) + #define FSMC_BCR_MTYP (0x3 << 2) + #define FSMC_BCR_MTYP_SRAM (0x0 << 2) + #define FSMC_BCR_MTYP_PSRAM (0x1 << 2) + #define FSMC_BCR_MTYP_NOR_FLASH (0x2 << 2) + #define FSMC_BCR_MUXEN (1U << FSMC_BCR_MUXEN_BIT) + #define FSMC_BCR_MBKEN (1U << FSMC_BCR_MBKEN_BIT) + + /* SRAM/NOR-Flash chip-select timing registers */ + + #define FSMC_BTR_ACCMOD (0x3 << 28) + #define FSMC_BTR_ACCMOD_A (0x0 << 28) + #define FSMC_BTR_ACCMOD_B (0x1 << 28) + #define FSMC_BTR_ACCMOD_C (0x2 << 28) + #define FSMC_BTR_ACCMOD_D (0x3 << 28) + #define FSMC_BTR_DATLAT (0xF << 24) + #define FSMC_BTR_CLKDIV (0xF << 20) + #define FSMC_BTR_BUSTURN (0xF << 16) + #define FSMC_BTR_DATAST (0xFF << 8) + #define FSMC_BTR_ADDHLD (0xF << 4) + #define FSMC_BTR_ADDSET 0xF + + /* SRAM/NOR-Flash write timing registers */ + + #define FSMC_BWTR_ACCMOD (0x3 << 28) + #define FSMC_BWTR_ACCMOD_A (0x0 << 28) + #define FSMC_BWTR_ACCMOD_B (0x1 << 28) + #define FSMC_BWTR_ACCMOD_C (0x2 << 28) + #define FSMC_BWTR_ACCMOD_D (0x3 << 28) + #define FSMC_BWTR_DATLAT (0xF << 24) + #define FSMC_BWTR_CLKDIV (0xF << 20) + #define FSMC_BWTR_DATAST (0xFF << 8) + #define FSMC_BWTR_ADDHLD (0xF << 4) + #define FSMC_BWTR_ADDSET 0xF + + /* NAND Flash/PC Card controller registers */ + + #define FSMC_PCR_ECCEN_BIT 6 + #define FSMC_PCR_PTYP_BIT 3 + #define FSMC_PCR_PBKEN_BIT 2 + #define FSMC_PCR_PWAITEN_BIT 1 + + #define FSMC_PCR_ECCPS (0x7 << 17) + #define FSMC_PCR_ECCPS_256B (0x0 << 17) + #define FSMC_PCR_ECCPS_512B (0x1 << 17) + #define FSMC_PCR_ECCPS_1024B (0x2 << 17) + #define FSMC_PCR_ECCPS_2048B (0x3 << 17) + #define FSMC_PCR_ECCPS_4096B (0x4 << 17) + #define FSMC_PCR_ECCPS_8192B (0x5 << 17) + #define FSMC_PCR_TAR (0xF << 13) + #define FSMC_PCR_TCLR (0xF << 9) + #define FSMC_PCR_ECCEN (1U << FSMC_PCR_ECCEN_BIT) + #define FSMC_PCR_PWID (0x3 << 4) + #define FSMC_PCR_PWID_8BITS (0x0 << 4) + #define FSMC_PCR_PWID_16BITS (0x1 << 4) + #define FSMC_PCR_PTYP (1U << FSMC_PCR_PTYP_BIT) + #define FSMC_PCR_PTYP_PC_CF_PCMCIA (0x0 << FSMC_PCR_PTYP_BIT) + #define FSMC_PCR_PTYP_NAND (0x1 << FSMC_PCR_PTYP_BIT) + #define FSMC_PCR_PBKEN (1U << FSMC_PCR_PBKEN_BIT) + #define FSMC_PCR_PWAITEN (1U << FSMC_PCR_PWAITEN_BIT) + + /* FIFO status and interrupt registers */ + + #define FSMC_SR_FEMPT_BIT 6 + #define FSMC_SR_IFEN_BIT 5 + #define FSMC_SR_ILEN_BIT 4 + #define FSMC_SR_IREN_BIT 3 + #define FSMC_SR_IFS_BIT 2 + #define FSMC_SR_ILS_BIT 1 + #define FSMC_SR_IRS_BIT 0 + + #define FSMC_SR_FEMPT (1U << FSMC_SR_FEMPT_BIT) + #define FSMC_SR_IFEN (1U << FSMC_SR_IFEN_BIT) + #define FSMC_SR_ILEN (1U << FSMC_SR_ILEN_BIT) + #define FSMC_SR_IREN (1U << FSMC_SR_IREN_BIT) + #define FSMC_SR_IFS (1U << FSMC_SR_IFS_BIT) + #define FSMC_SR_ILS (1U << FSMC_SR_ILS_BIT) + #define FSMC_SR_IRS (1U << FSMC_SR_IRS_BIT) + + /* Common memory space timing registers */ + + #define FSMC_PMEM_MEMHIZ (0xFF << 24) + #define FSMC_PMEM_MEMHOLD (0xFF << 16) + #define FSMC_PMEM_MEMWAIT (0xFF << 8) + #define FSMC_PMEM_MEMSET 0xFF + + /* Attribute memory space timing registers */ + + #define FSMC_PATT_ATTHIZ (0xFF << 24) + #define FSMC_PATT_ATTHOLD (0xFF << 16) + #define FSMC_PATT_ATTWAIT (0xFF << 8) + #define FSMC_PATT_ATTSET 0xFF + + /* I/O space timing register 4 */ + + #define FSMC_PIO_IOHIZ (0xFF << 24) + #define FSMC_PIO_IOHOLD (0xFF << 16) + #define FSMC_PIO_IOWAIT (0xFF << 8) + #define FSMC_PIO_IOSET 0xF diff --git a/docs/source/libmaple/api/gpio.rst b/docs/source/libmaple/api/gpio.rst new file mode 100644 index 0000000..faf0ad2 --- /dev/null +++ b/docs/source/libmaple/api/gpio.rst @@ -0,0 +1,243 @@ +.. highlight:: c +.. _libmaple-gpio: + +``gpio.h`` +========== + +General Purpose Input/Output (GPIO) port and Alternate Function +Input/Output (AFIO) support. + +.. contents:: Contents + :local: + +Types +----- + +.. doxygenstruct:: gpio_reg_map +.. doxygenstruct:: gpio_dev +.. doxygenenum:: gpio_pin_mode + +.. doxygenstruct:: afio_reg_map +.. doxygenenum:: afio_exti_port +.. doxygenenum:: afio_exti_num +.. doxygenenum:: afio_remap_peripheral +.. doxygenenum:: afio_debug_cfg + +Devices +------- + +.. doxygenvariable:: GPIOA +.. doxygenvariable:: GPIOB +.. doxygenvariable:: GPIOC +.. doxygenvariable:: GPIOD +.. doxygenvariable:: GPIOE +.. doxygenvariable:: GPIOF +.. doxygenvariable:: GPIOG + +Functions +--------- + +.. doxygenfunction:: gpio_init +.. doxygenfunction:: gpio_init_all +.. doxygenfunction:: gpio_set_mode +.. doxygenfunction:: gpio_exti_port +.. doxygenfunction:: gpio_write_bit +.. doxygenfunction:: gpio_read_bit +.. doxygenfunction:: gpio_toggle_bit + +.. doxygenfunction:: afio_init +.. doxygenfunction:: afio_exti_select + +.. _gpio-h-afio-remap: +.. doxygenfunction:: afio_remap +.. doxygenfunction:: afio_cfg_debug_ports + +Register Map Base Pointers +-------------------------- + +.. doxygendefine:: GPIOA_BASE +.. doxygendefine:: GPIOB_BASE +.. doxygendefine:: GPIOC_BASE +.. doxygendefine:: GPIOD_BASE +.. doxygendefine:: GPIOE_BASE +.. doxygendefine:: GPIOF_BASE +.. doxygendefine:: GPIOG_BASE + +.. doxygendefine:: AFIO_BASE + +Register Bit Definitions +------------------------ + +GPIO Control Registers +~~~~~~~~~~~~~~~~~~~~~~ + +These values apply to both the low and high configuration registers +(ST RM0008: GPIOx_CRL and GPIOx_CRH). You can shift them right by the +appropriate number of bits for the GPIO port bit you're interested in +to obtain a bit mask. + +For example, to mask out just the value of GPIOA_CRH_CNF12, note that +GPIO port bit 12's configuration starts at bit 18 in the corresponding +CRH. Thus, an appropriate mask is ``GPIOA_BASE->CRH & (GPIO_CR_CNF << +18)``. + +.. doxygendefine:: GPIO_CR_CNF_INPUT_ANALOG +.. doxygendefine:: GPIO_CR_CNF_INPUT_FLOATING +.. doxygendefine:: GPIO_CR_CNF_INPUT_PU_PD +.. doxygendefine:: GPIO_CR_CNF_OUTPUT_PP +.. doxygendefine:: GPIO_CR_CNF_OUTPUT_OD +.. doxygendefine:: GPIO_CR_CNF_AF_OUTPUT_PP +.. doxygendefine:: GPIO_CR_CNF_AF_OUTPUT_OD +.. doxygendefine:: GPIO_CR_MODE_INPUT +.. doxygendefine:: GPIO_CR_MODE_OUTPUT_10MHZ +.. doxygendefine:: GPIO_CR_MODE_OUTPUT_2MHZ +.. doxygendefine:: GPIO_CR_MODE_OUTPUT_50MHZ + +Event Control Register +~~~~~~~~~~~~~~~~~~~~~~ + +.. doxygendefine:: AFIO_EVCR_EVOE +.. doxygendefine:: AFIO_EVCR_PORT_PA +.. doxygendefine:: AFIO_EVCR_PORT_PB +.. doxygendefine:: AFIO_EVCR_PORT_PC +.. doxygendefine:: AFIO_EVCR_PORT_PD +.. doxygendefine:: AFIO_EVCR_PORT_PE +.. doxygendefine:: AFIO_EVCR_PIN_0 +.. doxygendefine:: AFIO_EVCR_PIN_1 +.. doxygendefine:: AFIO_EVCR_PIN_2 +.. doxygendefine:: AFIO_EVCR_PIN_3 +.. doxygendefine:: AFIO_EVCR_PIN_4 +.. doxygendefine:: AFIO_EVCR_PIN_5 +.. doxygendefine:: AFIO_EVCR_PIN_6 +.. doxygendefine:: AFIO_EVCR_PIN_7 +.. doxygendefine:: AFIO_EVCR_PIN_8 +.. doxygendefine:: AFIO_EVCR_PIN_9 +.. doxygendefine:: AFIO_EVCR_PIN_10 +.. doxygendefine:: AFIO_EVCR_PIN_11 +.. doxygendefine:: AFIO_EVCR_PIN_12 +.. doxygendefine:: AFIO_EVCR_PIN_13 +.. doxygendefine:: AFIO_EVCR_PIN_14 +.. doxygendefine:: AFIO_EVCR_PIN_15 + +AF Remap and Debug I/O Configuration Register +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. doxygendefine:: AFIO_MAPR_SWJ_CFG +.. doxygendefine:: AFIO_MAPR_SWJ_CFG_FULL_SWJ +.. doxygendefine:: AFIO_MAPR_SWJ_CFG_FULL_SWJ_NO_NJRST +.. doxygendefine:: AFIO_MAPR_SWJ_CFG_NO_JTAG_SW +.. doxygendefine:: AFIO_MAPR_SWJ_CFG_NO_JTAG_NO_SW +.. doxygendefine:: AFIO_MAPR_ADC2_ETRGREG_REMAP +.. doxygendefine:: AFIO_MAPR_ADC2_ETRGINJ_REMAP +.. doxygendefine:: AFIO_MAPR_ADC1_ETRGREG_REMAP +.. doxygendefine:: AFIO_MAPR_ADC1_ETRGINJ_REMAP +.. doxygendefine:: AFIO_MAPR_TIM5CH4_IREMAP +.. doxygendefine:: AFIO_MAPR_PD01_REMAP +.. doxygendefine:: AFIO_MAPR_CAN_REMAP +.. doxygendefine:: AFIO_MAPR_CAN_REMAP_NONE +.. doxygendefine:: AFIO_MAPR_CAN_REMAP_PB8_PB9 +.. doxygendefine:: AFIO_MAPR_CAN_REMAP_PD0_PD1 +.. doxygendefine:: AFIO_MAPR_TIM4_REMAP +.. doxygendefine:: AFIO_MAPR_TIM3_REMAP +.. doxygendefine:: AFIO_MAPR_TIM3_REMAP_NONE +.. doxygendefine:: AFIO_MAPR_TIM3_REMAP_PARTIAL +.. doxygendefine:: AFIO_MAPR_TIM3_REMAP_FULL +.. doxygendefine:: AFIO_MAPR_TIM2_REMAP +.. doxygendefine:: AFIO_MAPR_TIM2_REMAP_NONE +.. doxygendefine:: AFIO_MAPR_TIM2_REMAP_PA15_PB3_PA2_PA3 +.. doxygendefine:: AFIO_MAPR_TIM2_REMAP_PA0_PA1_PB10_PB11 +.. doxygendefine:: AFIO_MAPR_TIM2_REMAP_FULL +.. doxygendefine:: AFIO_MAPR_TIM1_REMAP +.. doxygendefine:: AFIO_MAPR_TIM1_REMAP_NONE +.. doxygendefine:: AFIO_MAPR_TIM1_REMAP_PARTIAL +.. doxygendefine:: AFIO_MAPR_TIM1_REMAP_FULL +.. doxygendefine:: AFIO_MAPR_USART3_REMAP +.. doxygendefine:: AFIO_MAPR_USART3_REMAP_NONE +.. doxygendefine:: AFIO_MAPR_USART3_REMAP_PARTIAL +.. doxygendefine:: AFIO_MAPR_USART3_REMAP_FULL +.. doxygendefine:: AFIO_MAPR_USART2_REMAP +.. doxygendefine:: AFIO_MAPR_USART1_REMAP +.. doxygendefine:: AFIO_MAPR_I2C1_REMAP +.. doxygendefine:: AFIO_MAPR_SPI1_REMAP + +External Interrupt Configuration Register 1 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. doxygendefine:: AFIO_EXTICR1_EXTI3 +.. doxygendefine:: AFIO_EXTICR1_EXTI3_PA +.. doxygendefine:: AFIO_EXTICR1_EXTI3_PB +.. doxygendefine:: AFIO_EXTICR1_EXTI3_PC +.. doxygendefine:: AFIO_EXTICR1_EXTI3_PD +.. doxygendefine:: AFIO_EXTICR1_EXTI3_PE +.. doxygendefine:: AFIO_EXTICR1_EXTI3_PF +.. doxygendefine:: AFIO_EXTICR1_EXTI3_PG +.. doxygendefine:: AFIO_EXTICR1_EXTI2 +.. doxygendefine:: AFIO_EXTICR1_EXTI2_PA +.. doxygendefine:: AFIO_EXTICR1_EXTI2_PB +.. doxygendefine:: AFIO_EXTICR1_EXTI2_PC +.. doxygendefine:: AFIO_EXTICR1_EXTI2_PD +.. doxygendefine:: AFIO_EXTICR1_EXTI2_PE +.. doxygendefine:: AFIO_EXTICR1_EXTI2_PF +.. doxygendefine:: AFIO_EXTICR1_EXTI2_PG +.. doxygendefine:: AFIO_EXTICR1_EXTI1 +.. doxygendefine:: AFIO_EXTICR1_EXTI1_PA +.. doxygendefine:: AFIO_EXTICR1_EXTI1_PB +.. doxygendefine:: AFIO_EXTICR1_EXTI1_PC +.. doxygendefine:: AFIO_EXTICR1_EXTI1_PD +.. doxygendefine:: AFIO_EXTICR1_EXTI1_PE +.. doxygendefine:: AFIO_EXTICR1_EXTI1_PF +.. doxygendefine:: AFIO_EXTICR1_EXTI1_PG +.. doxygendefine:: AFIO_EXTICR1_EXTI0 +.. doxygendefine:: AFIO_EXTICR1_EXTI0_PA +.. doxygendefine:: AFIO_EXTICR1_EXTI0_PB +.. doxygendefine:: AFIO_EXTICR1_EXTI0_PC +.. doxygendefine:: AFIO_EXTICR1_EXTI0_PD +.. doxygendefine:: AFIO_EXTICR1_EXTI0_PE +.. doxygendefine:: AFIO_EXTICR1_EXTI0_PF +.. doxygendefine:: AFIO_EXTICR1_EXTI0_PG + +External Interrupt Configuration Register 2 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. doxygendefine:: AFIO_EXTICR2_EXTI7 +.. doxygendefine:: AFIO_EXTICR2_EXTI7_PA +.. doxygendefine:: AFIO_EXTICR2_EXTI7_PB +.. doxygendefine:: AFIO_EXTICR2_EXTI7_PC +.. doxygendefine:: AFIO_EXTICR2_EXTI7_PD +.. doxygendefine:: AFIO_EXTICR2_EXTI7_PE +.. doxygendefine:: AFIO_EXTICR2_EXTI7_PF +.. doxygendefine:: AFIO_EXTICR2_EXTI7_PG +.. doxygendefine:: AFIO_EXTICR2_EXTI6 +.. doxygendefine:: AFIO_EXTICR2_EXTI6_PA +.. doxygendefine:: AFIO_EXTICR2_EXTI6_PB +.. doxygendefine:: AFIO_EXTICR2_EXTI6_PC +.. doxygendefine:: AFIO_EXTICR2_EXTI6_PD +.. doxygendefine:: AFIO_EXTICR2_EXTI6_PE +.. doxygendefine:: AFIO_EXTICR2_EXTI6_PF +.. doxygendefine:: AFIO_EXTICR2_EXTI6_PG +.. doxygendefine:: AFIO_EXTICR2_EXTI5 +.. doxygendefine:: AFIO_EXTICR2_EXTI5_PA +.. doxygendefine:: AFIO_EXTICR2_EXTI5_PB +.. doxygendefine:: AFIO_EXTICR2_EXTI5_PC +.. doxygendefine:: AFIO_EXTICR2_EXTI5_PD +.. doxygendefine:: AFIO_EXTICR2_EXTI5_PE +.. doxygendefine:: AFIO_EXTICR2_EXTI5_PF +.. doxygendefine:: AFIO_EXTICR2_EXTI5_PG +.. doxygendefine:: AFIO_EXTICR2_EXTI4 +.. doxygendefine:: AFIO_EXTICR2_EXTI4_PA +.. doxygendefine:: AFIO_EXTICR2_EXTI4_PB +.. doxygendefine:: AFIO_EXTICR2_EXTI4_PC +.. doxygendefine:: AFIO_EXTICR2_EXTI4_PD +.. doxygendefine:: AFIO_EXTICR2_EXTI4_PE +.. doxygendefine:: AFIO_EXTICR2_EXTI4_PF +.. doxygendefine:: AFIO_EXTICR2_EXTI4_PG + +AF Remap and Debug I/O Configuration Register 2 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. doxygendefine:: AFIO_MAPR2_FSMC_NADV +.. doxygendefine:: AFIO_MAPR2_TIM14_REMAP +.. doxygendefine:: AFIO_MAPR2_TIM13_REMAP +.. doxygendefine:: AFIO_MAPR2_TIM11_REMAP +.. doxygendefine:: AFIO_MAPR2_TIM10_REMAP +.. doxygendefine:: AFIO_MAPR2_TIM9_REMAP diff --git a/docs/source/libmaple/api/i2c.rst b/docs/source/libmaple/api/i2c.rst new file mode 100644 index 0000000..ff380cc --- /dev/null +++ b/docs/source/libmaple/api/i2c.rst @@ -0,0 +1,124 @@ +.. highlight:: c +.. _libmaple-i2c: + +``i2c.h`` +========= + +Inter-Integrated Circuit (|i2c|) peripheral support. + +.. contents:: Contents + :local: + +Important Note +-------------- + +There are some important known problems with the built-in I2C +peripherals. For more information, see STM32F10xx8 and STM32F10xxB +Errata sheet (ST Doc ID 14574 Rev 8), Section 2.11.1, 2.11.2. An +important consequence of these problems is that the |i2c| interrupt +must not be preempted. Consequently, (by default) Wirish uses an +|i2c| interrupt priority which is the highest in the system (priority +level 0). Other interrupt priorities are set lower. + +Types +----- + +.. doxygenstruct:: i2c_reg_map +.. doxygenenum:: i2c_state +.. doxygenstruct:: i2c_msg +.. doxygenstruct:: i2c_dev + +Devices +------- + +.. doxygenvariable:: I2C1 +.. doxygenvariable:: I2C2 + +Functions +--------- + +.. doxygenfunction:: i2c_init +.. doxygenfunction:: i2c_master_enable +.. doxygenfunction:: i2c_master_xfer +.. doxygenfunction:: i2c_bus_reset +.. doxygenfunction:: i2c_disable +.. doxygenfunction:: i2c_peripheral_enable +.. doxygenfunction:: i2c_peripheral_disable +.. doxygenfunction:: i2c_write +.. doxygenfunction:: i2c_set_input_clk +.. doxygenfunction:: i2c_set_clk_control +.. doxygenfunction:: i2c_set_trise +.. doxygenfunction:: i2c_start_condition +.. doxygenfunction:: i2c_stop_condition +.. doxygenfunction:: i2c_enable_irq +.. doxygenfunction:: i2c_disable_irq +.. doxygenfunction:: i2c_enable_ack +.. doxygenfunction:: i2c_disable_ack + +Register Map Base Pointers +-------------------------- + +.. doxygendefine:: I2C1_BASE +.. doxygendefine:: I2C2_BASE + +Register Bit Definitions +------------------------ + +Control register 1 +~~~~~~~~~~~~~~~~~~ + +.. doxygendefine:: I2C_CR1_SWRST +.. doxygendefine:: I2C_CR1_ALERT +.. doxygendefine:: I2C_CR1_PEC +.. doxygendefine:: I2C_CR1_POS +.. doxygendefine:: I2C_CR1_ACK +.. doxygendefine:: I2C_CR1_START +.. doxygendefine:: I2C_CR1_STOP +.. doxygendefine:: I2C_CR1_PE + +Control register 2 +~~~~~~~~~~~~~~~~~~ + +.. doxygendefine:: I2C_CR2_LAST +.. doxygendefine:: I2C_CR2_DMAEN +.. doxygendefine:: I2C_CR2_ITBUFEN +.. doxygendefine:: I2C_CR2_ITEVTEN +.. doxygendefine:: I2C_CR2_ITERREN +.. doxygendefine:: I2C_CR2_FREQ + +Clock control register +~~~~~~~~~~~~~~~~~~~~~~ + +.. doxygendefine:: I2C_CCR_FS +.. doxygendefine:: I2C_CCR_DUTY +.. doxygendefine:: I2C_CCR_CCR + +Status register 1 +~~~~~~~~~~~~~~~~~ + +.. doxygendefine:: I2C_SR1_SB +.. doxygendefine:: I2C_SR1_ADDR +.. doxygendefine:: I2C_SR1_BTF +.. doxygendefine:: I2C_SR1_ADD10 +.. doxygendefine:: I2C_SR1_STOPF +.. doxygendefine:: I2C_SR1_RXNE +.. doxygendefine:: I2C_SR1_TXE +.. doxygendefine:: I2C_SR1_BERR +.. doxygendefine:: I2C_SR1_ARLO +.. doxygendefine:: I2C_SR1_AF +.. doxygendefine:: I2C_SR1_OVR +.. doxygendefine:: I2C_SR1_PECERR +.. doxygendefine:: I2C_SR1_TIMEOUT +.. doxygendefine:: I2C_SR1_SMBALERT + +Status register 2 +~~~~~~~~~~~~~~~~~ + +.. doxygendefine:: I2C_SR2_MSL +.. doxygendefine:: I2C_SR2_BUSY +.. doxygendefine:: I2C_SR2_TRA +.. doxygendefine:: I2C_SR2_GENCALL +.. doxygendefine:: I2C_SR2_SMBDEFAULT +.. doxygendefine:: I2C_SR2_SMBHOST +.. doxygendefine:: I2C_SR2_DUALF +.. doxygendefine:: I2C_SR2_PEC diff --git a/docs/source/libmaple/api/iwdg.rst b/docs/source/libmaple/api/iwdg.rst new file mode 100644 index 0000000..65f9f7b --- /dev/null +++ b/docs/source/libmaple/api/iwdg.rst @@ -0,0 +1,80 @@ +.. highlight:: c +.. _libmaple-iwdg: + +``<libmaple/iwdg.h>`` +===================== + +Independent Watchdog (IWDG) support. The IWDG peripheral is common +across supported targets, so everything documented here is portable. + +.. contents:: Contents + :local: + +Usage Note +---------- + +To use the independent watchdog, first call :ref:`iwdg_init() +<libmaple-iwdg-iwdg_init>` with the appropriate prescaler and IWDG +counter reload values for your application. Afterwards, you must +periodically call :ref:`iwdg_feed() <libmaple-iwdg-iwdg_feed>` before +the IWDG counter reaches zero to reset the counter to its reload +value. If you do not, the chip will reset. + +Once started, the independent watchdog cannot be turned off. + +Devices +------- + +None at this time. + +Functions +--------- + +.. _libmaple-iwdg-iwdg_init: +.. doxygenfunction:: iwdg_init +.. _libmaple-iwdg-iwdg_feed: +.. doxygenfunction:: iwdg_feed + +Types +----- + +.. doxygenenum:: iwdg_prescaler + + +Register Maps +------------- + +.. doxygendefine:: IWDG_BASE + +.. doxygenstruct:: iwdg_reg_map + +Register Bit Definitions +------------------------ + +These are given as source code. + +:: + + /* Key register */ + + #define IWDG_KR_UNLOCK 0x5555 + #define IWDG_KR_FEED 0xAAAA + #define IWDG_KR_START 0xCCCC + + /* Prescaler register */ + + #define IWDG_PR_DIV_4 0x0 + #define IWDG_PR_DIV_8 0x1 + #define IWDG_PR_DIV_16 0x2 + #define IWDG_PR_DIV_32 0x3 + #define IWDG_PR_DIV_64 0x4 + #define IWDG_PR_DIV_128 0x5 + #define IWDG_PR_DIV_256 0x6 + + /* Status register */ + + #define IWDG_SR_RVU_BIT 1 + #define IWDG_SR_PVU_BIT 0 + + #define IWDG_SR_RVU (1U << IWDG_SR_RVU_BIT) + #define IWDG_SR_PVU (1U << IWDG_SR_PVU_BIT) diff --git a/docs/source/libmaple/api/libmaple.rst b/docs/source/libmaple/api/libmaple.rst new file mode 100644 index 0000000..7deb659 --- /dev/null +++ b/docs/source/libmaple/api/libmaple.rst @@ -0,0 +1,11 @@ +.. highlight:: c +.. _libmaple-libmaple: + +``<libmaple/libmaple.h>`` +========================= + +Base include file for libmaple. + +This file includes :ref:`libmaple-libmaple_types`, +:ref:`libmaple-stm32`, and :ref:`libmaple-util`. You shouldn't rely +on it doing anything else, however. diff --git a/docs/source/libmaple/api/libmaple_types.rst b/docs/source/libmaple/api/libmaple_types.rst new file mode 100644 index 0000000..5ca446e --- /dev/null +++ b/docs/source/libmaple/api/libmaple_types.rst @@ -0,0 +1,85 @@ +.. highlight:: c +.. _libmaple-libmaple_types: + +``<libmaple/libmaple_types.h>`` +=============================== + +Defines the base types and type-related macros used throughout the +rest of libmaple. + +.. contents:: Contents + :local: + +Integral Types +-------------- + +.. doxygentypedef:: uint8 +.. doxygentypedef:: uint16 +.. doxygentypedef:: uint32 +.. doxygentypedef:: uint64 +.. doxygentypedef:: int8 +.. doxygentypedef:: int16 +.. doxygentypedef:: int32 +.. doxygentypedef:: int64 + +Attributes and Type Qualifiers +------------------------------ + +In the case of macros for GCC's ``__attribute__``\ s, we have our own +macros mostly to save typing, but also in hopes that they might be +expressible using different compiler extensions, or to give them +different interpretations when running e.g. Doxygen on libmaple. + +.. c:macro:: __always_inline + + Macro for ``inline __attribute__((always_inline))``. This can be + used to defeat GCC's ``-Os`` when you Really Mean Inline. + +.. c:macro:: __attr_flash + + Macro for a GCC ``__attribute__`` which (when using libmaple's + linker scripts) will cause the variable being marked to be stored + in Flash, rather than SRAM. It's useful for read-only variables + like look-up tables. + +.. c:macro:: __deprecated + + Macro for ``__attribute__((deprecated))``. Its use causes GCC to + emit deprecation warnings when the deprecated functionality is + used. It's not used for everything that gets deprecated, so don't + rely on it to catch all uses of deprecated APIs. + +.. c:macro:: __packed + + Macro for ``__attribute__((packed))``. + +.. c:macro:: __io + + Macro for ``volatile`` which denotes that the variable whose type + is being qualified is IO-mapped. Its most common use is in the + individual members of each :ref:`register map + <libmaple-overview-regmaps>` struct. + +.. c:macro:: __weak + + Macro for ``__attribute__((weak))``. + +.. c:macro:: __unused + + Macro for ``__attribute__((unused))``. This can be used + (sparingly!) to silence unused function warnings when GCC is + mistaken. + +Miscellaneous +------------- + +.. doxygentypedef:: voidFuncPtr + +.. c:macro:: offsetof(type, member) + + If left undefined, this is defined to ``__builtin_ofsetof(type, + member)``. + +.. c:macro:: NULL + + If left undefined, this is defined to ``0``. diff --git a/docs/source/libmaple/api/nvic.rst b/docs/source/libmaple/api/nvic.rst new file mode 100644 index 0000000..505e36e --- /dev/null +++ b/docs/source/libmaple/api/nvic.rst @@ -0,0 +1,67 @@ +.. highlight:: c +.. _libmaple-nvic: + +``<libmaple/nvic.h>`` +===================== + +Nested Vector Interrupt Controller (NVIC) support. + +The same API is used on all targets, but the available interrupts are +target-dependent. To manage this, each target series defines an +:ref:`nvic_irq_num <libmaple-nvic-nvic_irq_num>` enumerator for each +available interrupt. + +.. contents:: Contents + :local: + +Devices +------- + +None at this time. + +.. _libmaple-nvic-nvic_irq_num: + +``nvic_irq_num`` +---------------- + +This target-dependent enum is used to identify an interrupt vector +number. Interrupts which are common across series have the same token +(though not necessarily the same value) for their ``nvic_irq_num``\ s. +The available values on each supported target series are as follows. + +STM32F1 Targets +~~~~~~~~~~~~~~~ + +.. doxygenenum:: stm32f1::nvic_irq_num + +STM32F2 Targets +~~~~~~~~~~~~~~~ + +.. doxygenenum:: stm32f2::nvic_irq_num + +Functions +--------- + +.. doxygenfunction:: nvic_init +.. doxygenfunction:: nvic_set_vector_table +.. doxygenfunction:: nvic_irq_set_priority +.. doxygenfunction:: nvic_globalirq_enable +.. doxygenfunction:: nvic_globalirq_disable +.. doxygenfunction:: nvic_irq_enable +.. doxygenfunction:: nvic_irq_disable +.. doxygenfunction:: nvic_irq_disable_all +.. doxygenfunction:: nvic_sys_reset + +Register Maps +------------- + +Since the NVIC is part of the ARM core, its registers and base pointer +are common across all targes. + +.. doxygendefine:: NVIC_BASE +.. doxygenstruct:: nvic_reg_map + +Register Bit Definitions +------------------------ + +None at this time. diff --git a/docs/source/libmaple/api/pwr.rst b/docs/source/libmaple/api/pwr.rst new file mode 100644 index 0000000..6a2cf22 --- /dev/null +++ b/docs/source/libmaple/api/pwr.rst @@ -0,0 +1,51 @@ +.. highlight:: c +.. _libmaple-pwr: + +``pwr.h`` +========= + +Power control (PWR) support. + +.. contents:: Contents + :local: + +Types +----- + +.. doxygenstruct:: pwr_reg_map + +Devices +------- + +None. + +Functions +--------- + +.. doxygenfunction:: pwr_init + +Register Map Base Pointers +-------------------------- + +.. doxygendefine:: PWR_BASE + +Register Bit Definitions +------------------------ + +Control register +~~~~~~~~~~~~~~~~ + +.. doxygendefine:: PWR_CR_DBP +.. doxygendefine:: PWR_CR_PVDE +.. doxygendefine:: PWR_CR_CSBF +.. doxygendefine:: PWR_CR_CWUF +.. doxygendefine:: PWR_CR_PDDS +.. doxygendefine:: PWR_CR_LPDS + +Control and status register +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. doxygendefine:: PWR_CSR_EWUP +.. doxygendefine:: PWR_CSR_PVDO +.. doxygendefine:: PWR_CSR_SBF +.. doxygendefine:: PWR_CSR_WUF diff --git a/docs/source/libmaple/api/rcc-reg-bits.txt b/docs/source/libmaple/api/rcc-reg-bits.txt new file mode 100644 index 0000000..6b1133d --- /dev/null +++ b/docs/source/libmaple/api/rcc-reg-bits.txt @@ -0,0 +1,1017 @@ +STM32F1 Targets +~~~~~~~~~~~~~~~ + +Clock control register +++++++++++++++++++++++ + +:: + + #define RCC_CR_PLLRDY_BIT 25 + #define RCC_CR_PLLON_BIT 24 + #define RCC_CR_CSSON_BIT 19 + #define RCC_CR_HSEBYP_BIT 18 + #define RCC_CR_HSERDY_BIT 17 + #define RCC_CR_HSEON_BIT 16 + #define RCC_CR_HSIRDY_BIT 1 + #define RCC_CR_HSION_BIT 0 + + #define RCC_CR_PLLRDY (1U << RCC_CR_PLLRDY_BIT) + #define RCC_CR_PLLON (1U << RCC_CR_PLLON_BIT) + #define RCC_CR_CSSON (1U << RCC_CR_CSSON_BIT) + #define RCC_CR_HSEBYP (1U << RCC_CR_HSEBYP_BIT) + #define RCC_CR_HSERDY (1U << RCC_CR_HSERDY_BIT) + #define RCC_CR_HSEON (1U << RCC_CR_HSEON_BIT) + #define RCC_CR_HSICAL (0xFF << 8) + #define RCC_CR_HSITRIM (0x1F << 3) + #define RCC_CR_HSIRDY (1U << RCC_CR_HSIRDY_BIT) + #define RCC_CR_HSION (1U << RCC_CR_HSION_BIT) + +Clock configuration register +++++++++++++++++++++++++++++ + +:: + + #define RCC_CFGR_USBPRE_BIT 22 + #define RCC_CFGR_PLLXTPRE_BIT 17 + #define RCC_CFGR_PLLSRC_BIT 16 + + #define RCC_CFGR_MCO (0x3 << 24) + #define RCC_CFGR_USBPRE (1U << RCC_CFGR_USBPRE_BIT) + #define RCC_CFGR_PLLMUL (0xF << 18) + #define RCC_CFGR_PLLXTPRE (1U << RCC_CFGR_PLLXTPRE_BIT) + #define RCC_CFGR_PLLSRC (1U << RCC_CFGR_PLLSRC_BIT) + #define RCC_CFGR_ADCPRE (0x3 << 14) + #define RCC_CFGR_PPRE2 (0x7 << 11) + #define RCC_CFGR_PPRE1 (0x7 << 8) + #define RCC_CFGR_HPRE (0xF << 4) + #define RCC_CFGR_SWS (0x3 << 2) + #define RCC_CFGR_SWS_PLL (0x2 << 2) + #define RCC_CFGR_SWS_HSE (0x1 << 2) + #define RCC_CFGR_SW 0x3 + #define RCC_CFGR_SW_PLL 0x2 + #define RCC_CFGR_SW_HSE 0x1 + +Clock interrupt register +++++++++++++++++++++++++ + +:: + + #define RCC_CIR_CSSC_BIT 23 + #define RCC_CIR_PLLRDYC_BIT 20 + #define RCC_CIR_HSERDYC_BIT 19 + #define RCC_CIR_HSIRDYC_BIT 18 + #define RCC_CIR_LSERDYC_BIT 17 + #define RCC_CIR_LSIRDYC_BIT 16 + #define RCC_CIR_PLLRDYIE_BIT 12 + #define RCC_CIR_HSERDYIE_BIT 11 + #define RCC_CIR_HSIRDYIE_BIT 10 + #define RCC_CIR_LSERDYIE_BIT 9 + #define RCC_CIR_LSIRDYIE_BIT 8 + #define RCC_CIR_CSSF_BIT 7 + #define RCC_CIR_PLLRDYF_BIT 4 + #define RCC_CIR_HSERDYF_BIT 3 + #define RCC_CIR_HSIRDYF_BIT 2 + #define RCC_CIR_LSERDYF_BIT 1 + #define RCC_CIR_LSIRDYF_BIT 0 + + #define RCC_CIR_CSSC (1U << RCC_CIR_CSSC_BIT) + #define RCC_CIR_PLLRDYC (1U << RCC_CIR_PLLRDYC_BIT) + #define RCC_CIR_HSERDYC (1U << RCC_CIR_HSERDYC_BIT) + #define RCC_CIR_HSIRDYC (1U << RCC_CIR_HSIRDYC_BIT) + #define RCC_CIR_LSERDYC (1U << RCC_CIR_LSERDYC_BIT) + #define RCC_CIR_LSIRDYC (1U << RCC_CIR_LSIRDYC_BIT) + #define RCC_CIR_PLLRDYIE (1U << RCC_CIR_PLLRDYIE_BIT) + #define RCC_CIR_HSERDYIE (1U << RCC_CIR_HSERDYIE_BIT) + #define RCC_CIR_HSIRDYIE (1U << RCC_CIR_HSIRDYIE_BIT) + #define RCC_CIR_LSERDYIE (1U << RCC_CIR_LSERDYIE_BIT) + #define RCC_CIR_LSIRDYIE (1U << RCC_CIR_LSIRDYIE_BIT) + #define RCC_CIR_CSSF (1U << RCC_CIR_CSSF_BIT) + #define RCC_CIR_PLLRDYF (1U << RCC_CIR_PLLRDYF_BIT) + #define RCC_CIR_HSERDYF (1U << RCC_CIR_HSERDYF_BIT) + #define RCC_CIR_HSIRDYF (1U << RCC_CIR_HSIRDYF_BIT) + #define RCC_CIR_LSERDYF (1U << RCC_CIR_LSERDYF_BIT) + #define RCC_CIR_LSIRDYF (1U << RCC_CIR_LSIRDYF_BIT) + +Peripheral reset registers +++++++++++++++++++++++++++ + +:: + + #define RCC_APB2RSTR_TIM11RST_BIT 21 + #define RCC_APB2RSTR_TIM10RST_BIT 20 + #define RCC_APB2RSTR_TIM9RST_BIT 19 + #define RCC_APB2RSTR_ADC3RST_BIT 15 + #define RCC_APB2RSTR_USART1RST_BIT 14 + #define RCC_APB2RSTR_TIM8RST_BIT 13 + #define RCC_APB2RSTR_SPI1RST_BIT 12 + #define RCC_APB2RSTR_TIM1RST_BIT 11 + #define RCC_APB2RSTR_ADC2RST_BIT 10 + #define RCC_APB2RSTR_ADC1RST_BIT 9 + #define RCC_APB2RSTR_IOPGRST_BIT 8 + #define RCC_APB2RSTR_IOPFRST_BIT 7 + #define RCC_APB2RSTR_IOPERST_BIT 6 + #define RCC_APB2RSTR_IOPDRST_BIT 5 + #define RCC_APB2RSTR_IOPCRST_BIT 4 + #define RCC_APB2RSTR_IOPBRST_BIT 3 + #define RCC_APB2RSTR_IOPARST_BIT 2 + #define RCC_APB2RSTR_AFIORST_BIT 0 + + #define RCC_APB2RSTR_TIM11RST (1U << RCC_APB2RSTR_TIM11RST_BIT) + #define RCC_APB2RSTR_TIM10RST (1U << RCC_APB2RSTR_TIM10RST_BIT) + #define RCC_APB2RSTR_TIM9RST (1U << RCC_APB2RSTR_TIM9RST_BIT) + #define RCC_APB2RSTR_ADC3RST (1U << RCC_APB2RSTR_ADC3RST_BIT) + #define RCC_APB2RSTR_USART1RST (1U << RCC_APB2RSTR_USART1RST_BIT) + #define RCC_APB2RSTR_TIM8RST (1U << RCC_APB2RSTR_TIM8RST_BIT) + #define RCC_APB2RSTR_SPI1RST (1U << RCC_APB2RSTR_SPI1RST_BIT) + #define RCC_APB2RSTR_TIM1RST (1U << RCC_APB2RSTR_TIM1RST_BIT) + #define RCC_APB2RSTR_ADC2RST (1U << RCC_APB2RSTR_ADC2RST_BIT) + #define RCC_APB2RSTR_ADC1RST (1U << RCC_APB2RSTR_ADC1RST_BIT) + #define RCC_APB2RSTR_IOPGRST (1U << RCC_APB2RSTR_IOPGRST_BIT) + #define RCC_APB2RSTR_IOPFRST (1U << RCC_APB2RSTR_IOPFRST_BIT) + #define RCC_APB2RSTR_IOPERST (1U << RCC_APB2RSTR_IOPERST_BIT) + #define RCC_APB2RSTR_IOPDRST (1U << RCC_APB2RSTR_IOPDRST_BIT) + #define RCC_APB2RSTR_IOPCRST (1U << RCC_APB2RSTR_IOPCRST_BIT) + #define RCC_APB2RSTR_IOPBRST (1U << RCC_APB2RSTR_IOPBRST_BIT) + #define RCC_APB2RSTR_IOPARST (1U << RCC_APB2RSTR_IOPARST_BIT) + #define RCC_APB2RSTR_AFIORST (1U << RCC_APB2RSTR_AFIORST_BIT) + + #define RCC_APB1RSTR_DACRST_BIT 29 + #define RCC_APB1RSTR_PWRRST_BIT 28 + #define RCC_APB1RSTR_BKPRST_BIT 27 + #define RCC_APB1RSTR_CANRST_BIT 25 + #define RCC_APB1RSTR_USBRST_BIT 23 + #define RCC_APB1RSTR_I2C2RST_BIT 22 + #define RCC_APB1RSTR_I2C1RST_BIT 21 + #define RCC_APB1RSTR_UART5RST_BIT 20 + #define RCC_APB1RSTR_UART4RST_BIT 19 + #define RCC_APB1RSTR_USART3RST_BIT 18 + #define RCC_APB1RSTR_USART2RST_BIT 17 + #define RCC_APB1RSTR_SPI3RST_BIT 15 + #define RCC_APB1RSTR_SPI2RST_BIT 14 + #define RCC_APB1RSTR_WWDRST_BIT 11 + #define RCC_APB1RSTR_TIM14RST_BIT 8 + #define RCC_APB1RSTR_TIM13RST_BIT 7 + #define RCC_APB1RSTR_TIM12RST_BIT 6 + #define RCC_APB1RSTR_TIM7RST_BIT 5 + #define RCC_APB1RSTR_TIM6RST_BIT 4 + #define RCC_APB1RSTR_TIM5RST_BIT 3 + #define RCC_APB1RSTR_TIM4RST_BIT 2 + #define RCC_APB1RSTR_TIM3RST_BIT 1 + #define RCC_APB1RSTR_TIM2RST_BIT 0 + + #define RCC_APB1RSTR_DACRST (1U << RCC_APB1RSTR_DACRST_BIT) + #define RCC_APB1RSTR_PWRRST (1U << RCC_APB1RSTR_PWRRST_BIT) + #define RCC_APB1RSTR_BKPRST (1U << RCC_APB1RSTR_BKPRST_BIT) + #define RCC_APB1RSTR_CANRST (1U << RCC_APB1RSTR_CANRST_BIT) + #define RCC_APB1RSTR_USBRST (1U << RCC_APB1RSTR_USBRST_BIT) + #define RCC_APB1RSTR_I2C2RST (1U << RCC_APB1RSTR_I2C2RST_BIT) + #define RCC_APB1RSTR_I2C1RST (1U << RCC_APB1RSTR_I2C1RST_BIT) + #define RCC_APB1RSTR_UART5RST (1U << RCC_APB1RSTR_UART5RST_BIT) + #define RCC_APB1RSTR_UART4RST (1U << RCC_APB1RSTR_UART4RST_BIT) + #define RCC_APB1RSTR_USART3RST (1U << RCC_APB1RSTR_USART3RST_BIT) + #define RCC_APB1RSTR_USART2RST (1U << RCC_APB1RSTR_USART2RST_BIT) + #define RCC_APB1RSTR_SPI3RST (1U << RCC_APB1RSTR_SPI3RST_BIT) + #define RCC_APB1RSTR_SPI2RST (1U << RCC_APB1RSTR_SPI2RST_BIT) + #define RCC_APB1RSTR_WWDRST (1U << RCC_APB1RSTR_WWDRST_BIT) + #define RCC_APB1RSTR_TIM14RST (1U << RCC_APB1RSTR_TIM14RST_BIT) + #define RCC_APB1RSTR_TIM13RST (1U << RCC_APB1RSTR_TIM13RST_BIT) + #define RCC_APB1RSTR_TIM12RST (1U << RCC_APB1RSTR_TIM12RST_BIT) + #define RCC_APB1RSTR_TIM7RST (1U << RCC_APB1RSTR_TIM7RST_BIT) + #define RCC_APB1RSTR_TIM6RST (1U << RCC_APB1RSTR_TIM6RST_BIT) + #define RCC_APB1RSTR_TIM5RST (1U << RCC_APB1RSTR_TIM5RST_BIT) + #define RCC_APB1RSTR_TIM4RST (1U << RCC_APB1RSTR_TIM4RST_BIT) + #define RCC_APB1RSTR_TIM3RST (1U << RCC_APB1RSTR_TIM3RST_BIT) + #define RCC_APB1RSTR_TIM2RST (1U << RCC_APB1RSTR_TIM2RST_BIT) + +Peripheral clock enable registers ++++++++++++++++++++++++++++++++++ + +:: + + #define RCC_AHBENR_SDIOEN_BIT 10 + #define RCC_AHBENR_FSMCEN_BIT 8 + #define RCC_AHBENR_CRCEN_BIT 7 + #define RCC_AHBENR_FLITFEN_BIT 4 + #define RCC_AHBENR_SRAMEN_BIT 2 + #define RCC_AHBENR_DMA2EN_BIT 1 + #define RCC_AHBENR_DMA1EN_BIT 0 + + #define RCC_AHBENR_SDIOEN (1U << RCC_AHBENR_SDIOEN_BIT) + #define RCC_AHBENR_FSMCEN (1U << RCC_AHBENR_FSMCEN_BIT) + #define RCC_AHBENR_CRCEN (1U << RCC_AHBENR_CRCEN_BIT) + #define RCC_AHBENR_FLITFEN (1U << RCC_AHBENR_FLITFEN_BIT) + #define RCC_AHBENR_SRAMEN (1U << RCC_AHBENR_SRAMEN_BIT) + #define RCC_AHBENR_DMA2EN (1U << RCC_AHBENR_DMA2EN_BIT) + #define RCC_AHBENR_DMA1EN (1U << RCC_AHBENR_DMA1EN_BIT) + + #define RCC_APB2ENR_TIM11EN_BIT 21 + #define RCC_APB2ENR_TIM10EN_BIT 20 + #define RCC_APB2ENR_TIM9EN_BIT 19 + #define RCC_APB2ENR_ADC3EN_BIT 15 + #define RCC_APB2ENR_USART1EN_BIT 14 + #define RCC_APB2ENR_TIM8EN_BIT 13 + #define RCC_APB2ENR_SPI1EN_BIT 12 + #define RCC_APB2ENR_TIM1EN_BIT 11 + #define RCC_APB2ENR_ADC2EN_BIT 10 + #define RCC_APB2ENR_ADC1EN_BIT 9 + #define RCC_APB2ENR_IOPGEN_BIT 8 + #define RCC_APB2ENR_IOPFEN_BIT 7 + #define RCC_APB2ENR_IOPEEN_BIT 6 + #define RCC_APB2ENR_IOPDEN_BIT 5 + #define RCC_APB2ENR_IOPCEN_BIT 4 + #define RCC_APB2ENR_IOPBEN_BIT 3 + #define RCC_APB2ENR_IOPAEN_BIT 2 + #define RCC_APB2ENR_AFIOEN_BIT 0 + + #define RCC_APB2ENR_TIM11EN (1U << RCC_APB2ENR_TIM11EN_BIT) + #define RCC_APB2ENR_TIM10EN (1U << RCC_APB2ENR_TIM10EN_BIT) + #define RCC_APB2ENR_TIM9EN (1U << RCC_APB2ENR_TIM9EN_BIT) + #define RCC_APB2ENR_ADC3EN (1U << RCC_APB2ENR_ADC3EN_BIT) + #define RCC_APB2ENR_USART1EN (1U << RCC_APB2ENR_USART1EN_BIT) + #define RCC_APB2ENR_TIM8EN (1U << RCC_APB2ENR_TIM8EN_BIT) + #define RCC_APB2ENR_SPI1EN (1U << RCC_APB2ENR_SPI1EN_BIT) + #define RCC_APB2ENR_TIM1EN (1U << RCC_APB2ENR_TIM1EN_BIT) + #define RCC_APB2ENR_ADC2EN (1U << RCC_APB2ENR_ADC2EN_BIT) + #define RCC_APB2ENR_ADC1EN (1U << RCC_APB2ENR_ADC1EN_BIT) + #define RCC_APB2ENR_IOPGEN (1U << RCC_APB2ENR_IOPGEN_BIT) + #define RCC_APB2ENR_IOPFEN (1U << RCC_APB2ENR_IOPFEN_BIT) + #define RCC_APB2ENR_IOPEEN (1U << RCC_APB2ENR_IOPEEN_BIT) + #define RCC_APB2ENR_IOPDEN (1U << RCC_APB2ENR_IOPDEN_BIT) + #define RCC_APB2ENR_IOPCEN (1U << RCC_APB2ENR_IOPCEN_BIT) + #define RCC_APB2ENR_IOPBEN (1U << RCC_APB2ENR_IOPBEN_BIT) + #define RCC_APB2ENR_IOPAEN (1U << RCC_APB2ENR_IOPAEN_BIT) + #define RCC_APB2ENR_AFIOEN (1U << RCC_APB2ENR_AFIOEN_BIT) + + #define RCC_APB1ENR_DACEN_BIT 29 + #define RCC_APB1ENR_PWREN_BIT 28 + #define RCC_APB1ENR_BKPEN_BIT 27 + #define RCC_APB1ENR_CANEN_BIT 25 + #define RCC_APB1ENR_USBEN_BIT 23 + #define RCC_APB1ENR_I2C2EN_BIT 22 + #define RCC_APB1ENR_I2C1EN_BIT 21 + #define RCC_APB1ENR_UART5EN_BIT 20 + #define RCC_APB1ENR_UART4EN_BIT 19 + #define RCC_APB1ENR_USART3EN_BIT 18 + #define RCC_APB1ENR_USART2EN_BIT 17 + #define RCC_APB1ENR_SPI3EN_BIT 15 + #define RCC_APB1ENR_SPI2EN_BIT 14 + #define RCC_APB1ENR_WWDEN_BIT 11 + #define RCC_APB1ENR_TIM14EN_BIT 8 + #define RCC_APB1ENR_TIM13EN_BIT 7 + #define RCC_APB1ENR_TIM12EN_BIT 6 + #define RCC_APB1ENR_TIM7EN_BIT 5 + #define RCC_APB1ENR_TIM6EN_BIT 4 + #define RCC_APB1ENR_TIM5EN_BIT 3 + #define RCC_APB1ENR_TIM4EN_BIT 2 + #define RCC_APB1ENR_TIM3EN_BIT 1 + #define RCC_APB1ENR_TIM2EN_BIT 0 + + #define RCC_APB1ENR_DACEN (1U << RCC_APB1ENR_DACEN_BIT) + #define RCC_APB1ENR_PWREN (1U << RCC_APB1ENR_PWREN_BIT) + #define RCC_APB1ENR_BKPEN (1U << RCC_APB1ENR_BKPEN_BIT) + #define RCC_APB1ENR_CANEN (1U << RCC_APB1ENR_CANEN_BIT) + #define RCC_APB1ENR_USBEN (1U << RCC_APB1ENR_USBEN_BIT) + #define RCC_APB1ENR_I2C2EN (1U << RCC_APB1ENR_I2C2EN_BIT) + #define RCC_APB1ENR_I2C1EN (1U << RCC_APB1ENR_I2C1EN_BIT) + #define RCC_APB1ENR_UART5EN (1U << RCC_APB1ENR_UART5EN_BIT) + #define RCC_APB1ENR_UART4EN (1U << RCC_APB1ENR_UART4EN_BIT) + #define RCC_APB1ENR_USART3EN (1U << RCC_APB1ENR_USART3EN_BIT) + #define RCC_APB1ENR_USART2EN (1U << RCC_APB1ENR_USART2EN_BIT) + #define RCC_APB1ENR_SPI3EN (1U << RCC_APB1ENR_SPI3EN_BIT) + #define RCC_APB1ENR_SPI2EN (1U << RCC_APB1ENR_SPI2EN_BIT) + #define RCC_APB1ENR_WWDEN (1U << RCC_APB1ENR_WWDEN_BIT) + #define RCC_APB1ENR_TIM14EN (1U << RCC_APB1ENR_TIM14EN_BIT) + #define RCC_APB1ENR_TIM13EN (1U << RCC_APB1ENR_TIM13EN_BIT) + #define RCC_APB1ENR_TIM12EN (1U << RCC_APB1ENR_TIM12EN_BIT) + #define RCC_APB1ENR_TIM7EN (1U << RCC_APB1ENR_TIM7EN_BIT) + #define RCC_APB1ENR_TIM6EN (1U << RCC_APB1ENR_TIM6EN_BIT) + #define RCC_APB1ENR_TIM5EN (1U << RCC_APB1ENR_TIM5EN_BIT) + #define RCC_APB1ENR_TIM4EN (1U << RCC_APB1ENR_TIM4EN_BIT) + #define RCC_APB1ENR_TIM3EN (1U << RCC_APB1ENR_TIM3EN_BIT) + #define RCC_APB1ENR_TIM2EN (1U << RCC_APB1ENR_TIM2EN_BIT) + +Backup domain control register +++++++++++++++++++++++++++++++ + +:: + + #define RCC_BDCR_BDRST_BIT 16 + #define RCC_BDCR_RTCEN_BIT 15 + #define RCC_BDCR_LSEBYP_BIT 2 + #define RCC_BDCR_LSERDY_BIT 1 + #define RCC_BDCR_LSEON_BIT 0 + + #define RCC_BDCR_BDRST (1U << RCC_BDCR_BDRST_BIT) + #define RCC_BDCR_RTCEN (1U << RCC_BDCR_RTC_BIT) + #define RCC_BDCR_RTCSEL (0x3 << 8) + #define RCC_BDCR_RTCSEL_NONE (0x0 << 8) + #define RCC_BDCR_RTCSEL_LSE (0x1 << 8) + #define RCC_BDCR_RTCSEL_HSE (0x3 << 8) + #define RCC_BDCR_LSEBYP (1U << RCC_BDCR_LSEBYP_BIT) + #define RCC_BDCR_LSERDY (1U << RCC_BDCR_LSERDY_BIT) + #define RCC_BDCR_LSEON (1U << RCC_BDCR_LSEON_BIT) + +Control/status register ++++++++++++++++++++++++ + +:: + + #define RCC_CSR_LPWRRSTF_BIT 31 + #define RCC_CSR_WWDGRSTF_BIT 30 + #define RCC_CSR_IWDGRSTF_BIT 29 + #define RCC_CSR_SFTRSTF_BIT 28 + #define RCC_CSR_PORRSTF_BIT 27 + #define RCC_CSR_PINRSTF_BIT 26 + #define RCC_CSR_RMVF_BIT 24 + #define RCC_CSR_LSIRDY_BIT 1 + #define RCC_CSR_LSION_BIT 0 + + #define RCC_CSR_LPWRRSTF (1U << RCC_CSR_LPWRRSTF_BIT) + #define RCC_CSR_WWDGRSTF (1U << RCC_CSR_WWDGRSTF_BIT) + #define RCC_CSR_IWDGRSTF (1U << RCC_CSR_IWDGRSTF_BIT) + #define RCC_CSR_SFTRSTF (1U << RCC_CSR_SFTRSTF_BIT) + #define RCC_CSR_PORRSTF (1U << RCC_CSR_PORRSTF_BIT) + #define RCC_CSR_PINRSTF (1U << RCC_CSR_PINRSTF_BIT) + #define RCC_CSR_RMVF (1U << RCC_CSR_RMVF_BIT) + #define RCC_CSR_LSIRDY (1U << RCC_CSR_LSIRDY_BIT) + #define RCC_CSR_LSION (1U << RCC_CSR_LSION_BIT) + +STM32F2 Targets +~~~~~~~~~~~~~~~ + +Clock control register +++++++++++++++++++++++ + +:: + + #define RCC_CR_PLLI2SRDY_BIT 27 + #define RCC_CR_PLLI2SON_BIT 26 + #define RCC_CR_PLLRDY_BIT 25 + #define RCC_CR_PLLON_BIT 24 + #define RCC_CR_CSSON_BIT 19 + #define RCC_CR_HSEBYP_BIT 18 + #define RCC_CR_HSERDY_BIT 17 + #define RCC_CR_HSEON_BIT 16 + #define RCC_CR_HSIRDY_BIT 1 + #define RCC_CR_HSION_BIT 0 + + #define RCC_CR_PLLI2SRDY (1U << RCC_CR_PLLI2SRDY_BIT) + #define RCC_CR_PLLI2SON (1U << RCC_CR_PLLI2SON_BIT) + #define RCC_CR_PLLRDY (1U << RCC_CR_PLLRDY_BIT) + #define RCC_CR_PLLON (1U << RCC_CR_PLLON_BIT) + #define RCC_CR_CSSON (1U << RCC_CR_CSSON_BIT) + #define RCC_CR_HSEBYP (1U << RCC_CR_HSEBYP_BIT) + #define RCC_CR_HSERDY (1U << RCC_CR_HSERDY_BIT) + #define RCC_CR_HSEON (1U << RCC_CR_HSEON_BIT) + #define RCC_CR_HSICAL (0xFF << 8) + #define RCC_CR_HSITRIM (0x1F << 3) + #define RCC_CR_HSIRDY (1U << RCC_CR_HSIRDY_BIT) + #define RCC_CR_HSION (1U << RCC_CR_HSION_BIT) + +PLL configuration register +++++++++++++++++++++++++++ + +:: + + #define RCC_PLLCFGR_PLLSRC_BIT 22 + + #define RCC_PLLCFGR_PLLQ (0xF << 24) + #define RCC_PLLCFGR_PLLSRC (1U << RCC_PLLCFGR_PLLSRC_BIT) + #define RCC_PLLCFGR_PLLSRC_HSI (0x0 << RCC_PLLCFGR_PLLSRC_BIT) + #define RCC_PLLCFGR_PLLSRC_HSE (0x1 << RCC_PLLCFGR_PLLSRC_BIT) + #define RCC_PLLCFGR_PLLP (0x3 << 16) + #define RCC_PLLCFGR_PLLN (0x1FF << 6) + #define RCC_PLLCFGR_PLLM 0x1F + +Clock configuration register +++++++++++++++++++++++++++++ + +:: + + #define RCC_CFGR_I2SSRC_BIT 23 + + #define RCC_CFGR_MCO2 (0x3 << 30) + #define RCC_CFGR_MCO2_SYSCLK (0x0 << 30) + #define RCC_CFGR_MCO2_PLLI2S (0x1 << 30) + #define RCC_CFGR_MCO2_HSE (0x2 << 30) + #define RCC_CFGR_MCO2_PLL (0x3 << 30) + + #define RCC_CFGR_MCO2PRE (0x7 << 27) + #define RCC_CFGR_MCO2PRE_DIV_1 (0x0 << 27) + #define RCC_CFGR_MCO2PRE_DIV_2 (0x4 << 27) + #define RCC_CFGR_MCO2PRE_DIV_3 (0x5 << 27) + #define RCC_CFGR_MCO2PRE_DIV_4 (0x6 << 27) + #define RCC_CFGR_MCO2PRE_DIV_5 (0x7 << 27) + + #define RCC_CFGR_MCO1PRE (0x7 << 24) + #define RCC_CFGR_MCO1PRE_DIV_1 (0x0 << 24) + #define RCC_CFGR_MCO1PRE_DIV_2 (0x4 << 24) + #define RCC_CFGR_MCO1PRE_DIV_3 (0x5 << 24) + #define RCC_CFGR_MCO1PRE_DIV_4 (0x6 << 24) + #define RCC_CFGR_MCO1PRE_DIV_5 (0x7 << 24) + + #define RCC_CFGR_I2SSRC (1U << RCC_CFGR_I2SSRC_BIT) + #define RCC_CFGR_I2SSRC_PLLI2S (0 << RCC_CFGR_I2SSRC_BIT) + #define RCC_CFGR_I2SSRC_I2S_CKIN (1 << RCC_CFGR_I2SSRC_BIT) + + #define RCC_CFGR_MCO1 (0x3 << 21) + #define RCC_CFGR_MCO1_HSI (0x0 << 21) + #define RCC_CFGR_MCO1_LSE (0x1 << 21) + #define RCC_CFGR_MCO1_HSE (0x2 << 21) + #define RCC_CFGR_MCO1_PLL (0x3 << 21) + + #define RCC_CFGR_RTCPRE (0x1F << 16) + + /* Skipped: all the 0b0xx values meaning "not divided" */ + #define RCC_CFGR_PPRE2 (0x7 << 13) + #define RCC_CFGR_PPRE2_AHB_DIV_2 (0x4 << 13) + #define RCC_CFGR_PPRE2_AHB_DIV_4 (0x5 << 13) + #define RCC_CFGR_PPRE2_AHB_DIV_8 (0x6 << 13) + #define RCC_CFGR_PPRE2_AHB_DIV_16 (0x7 << 13) + + /* Skipped: all the 0b0xx values meaning "not divided" */ + #define RCC_CFGR_PPRE1 (0x7 << 10) + #define RCC_CFGR_PPRE1_AHB_DIV_2 (0x4 << 10) + #define RCC_CFGR_PPRE1_AHB_DIV_4 (0x5 << 10) + #define RCC_CFGR_PPRE1_AHB_DIV_8 (0x6 << 10) + #define RCC_CFGR_PPRE1_AHB_DIV_16 (0x7 << 10) + + /* Skipped: all the 0b0xxx values meaning "not divided" */ + #define RCC_CFGR_HPRE (0xF << 4) + #define RCC_CFGR_HPRE_SYSCLK_DIV_2 (0x8 << 4) + #define RCC_CFGR_HPRE_SYSCLK_DIV_4 (0x9 << 4) + #define RCC_CFGR_HPRE_SYSCLK_DIV_8 (0xA << 4) + #define RCC_CFGR_HPRE_SYSCLK_DIV_16 (0xB << 4) + #define RCC_CFGR_HPRE_SYSCLK_DIV_64 (0xC << 4) + #define RCC_CFGR_HPRE_SYSCLK_DIV_128 (0xD << 4) + #define RCC_CFGR_HPRE_SYSCLK_DIV_256 (0xE << 4) + #define RCC_CFGR_HPRE_SYSCLK_DIV_512 (0xF << 4) + + #define RCC_CFGR_SWS (0x3 << 2) + #define RCC_CFGR_SWS_HSI (0x0 << 2) + #define RCC_CFGR_SWS_HSE (0x1 << 2) + #define RCC_CFGR_SWS_PLL (0x2 << 2) + + #define RCC_CFGR_SW 0x3 + #define RCC_CFGR_SW_HSI 0x0 + #define RCC_CFGR_SW_HSE 0x1 + #define RCC_CFGR_SW_PLL 0x2 + +Clock interrupt register +++++++++++++++++++++++++ + +:: + + #define RCC_CIR_CSSC_BIT 23 + + #define RCC_CIR_PLLI2SRDYC_BIT 21 + #define RCC_CIR_PLLRDYC_BIT 20 + #define RCC_CIR_HSERDYC_BIT 19 + #define RCC_CIR_HSIRDYC_BIT 18 + #define RCC_CIR_LSERDYC_BIT 17 + #define RCC_CIR_LSIRDYC_BIT 16 + + #define RCC_CIR_PLLI2SRDYIE_BIT 13 + #define RCC_CIR_PLLRDYIE_BIT 12 + #define RCC_CIR_HSERDYIE_BIT 11 + #define RCC_CIR_HSIRDYIE_BIT 10 + #define RCC_CIR_LSERDYIE_BIT 9 + #define RCC_CIR_LSIRDYIE_BIT 8 + + #define RCC_CIR_CSSF_BIT 7 + + #define RCC_CIR_PLLI2SRDYF_BIT 5 + #define RCC_CIR_PLLRDYF_BIT 4 + #define RCC_CIR_HSERDYF_BIT 3 + #define RCC_CIR_HSIRDYF_BIT 2 + #define RCC_CIR_LSERDYF_BIT 1 + #define RCC_CIR_LSIRDYF_BIT 0 + + #define RCC_CIR_CSSC (1U << RCC_CIR_CSSC_BIT) + + #define RCC_CIR_PLLI2SRDYC (1U << RCC_CIR_PLLI2SRDYC_BIT) + #define RCC_CIR_PLLRDYC (1U << RCC_CIR_PLLRDYC_BIT) + #define RCC_CIR_HSERDYC (1U << RCC_CIR_HSERDYC_BIT) + #define RCC_CIR_HSIRDYC (1U << RCC_CIR_HSIRDYC_BIT) + #define RCC_CIR_LSERDYC (1U << RCC_CIR_LSERDYC_BIT) + #define RCC_CIR_LSIRDYC (1U << RCC_CIR_LSIRDYC_BIT) + + #define RCC_CIR_PLLI2SRDYIE (1U << RCC_CIR_PLLI2SRDYIE_BIT) + #define RCC_CIR_PLLRDYIE (1U << RCC_CIR_PLLRDYIE_BIT) + #define RCC_CIR_HSERDYIE (1U << RCC_CIR_HSERDYIE_BIT) + #define RCC_CIR_HSIRDYIE (1U << RCC_CIR_HSIRDYIE_BIT) + #define RCC_CIR_LSERDYIE (1U << RCC_CIR_LSERDYIE_BIT) + #define RCC_CIR_LSIRDYIE (1U << RCC_CIR_LSIRDYIE_BIT) + + #define RCC_CIR_CSSF (1U << RCC_CIR_CSSF_BIT) + + #define RCC_CIR_PLLI2SRDYF (1U << RCC_CIR_PLLI2SRDYF_BIT) + #define RCC_CIR_PLLRDYF (1U << RCC_CIR_PLLRDYF_BIT) + #define RCC_CIR_HSERDYF (1U << RCC_CIR_HSERDYF_BIT) + #define RCC_CIR_HSIRDYF (1U << RCC_CIR_HSIRDYF_BIT) + #define RCC_CIR_LSERDYF (1U << RCC_CIR_LSERDYF_BIT) + #define RCC_CIR_LSIRDYF (1U << RCC_CIR_LSIRDYF_BIT) + +Peripheral reset registers +++++++++++++++++++++++++++ + +:: + + /* AHB1 */ + + #define RCC_AHB1RSTR_OTGHSRST_BIT 29 + #define RCC_AHB1RSTR_ETHMACRST_BIT 25 + #define RCC_AHB1RSTR_DMA2RST_BIT 22 + #define RCC_AHB1RSTR_DMA1RST_BIT 21 + #define RCC_AHB1RSTR_CRCRST_BIT 12 + #define RCC_AHB1RSTR_GPIOIRST_BIT 8 + #define RCC_AHB1RSTR_GPIOHRST_BIT 7 + #define RCC_AHB1RSTR_GPIOGRST_BIT 6 + #define RCC_AHB1RSTR_GPIOFRST_BIT 5 + #define RCC_AHB1RSTR_GPIOERST_BIT 4 + #define RCC_AHB1RSTR_GPIODRST_BIT 3 + #define RCC_AHB1RSTR_GPIOCRST_BIT 2 + #define RCC_AHB1RSTR_GPIOBRST_BIT 1 + #define RCC_AHB1RSTR_GPIOARST_BIT 0 + + #define RCC_AHB1RSTR_OTGHSRST (1U << RCC_AHB1RSTR_OTGHSRST_BIT) + #define RCC_AHB1RSTR_ETHMACRST (1U << RCC_AHB1RSTR_ETHMACRST_BIT) + #define RCC_AHB1RSTR_DMA2RST (1U << RCC_AHB1RSTR_DMA2RST_BIT) + #define RCC_AHB1RSTR_DMA1RST (1U << RCC_AHB1RSTR_DMA1RST_BIT) + #define RCC_AHB1RSTR_CRCRST (1U << RCC_AHB1RSTR_CRCRST_BIT) + #define RCC_AHB1RSTR_GPIOIRST (1U << RCC_AHB1RSTR_GPIOIRST_BIT) + #define RCC_AHB1RSTR_GPIOHRST (1U << RCC_AHB1RSTR_GPIOHRST_BIT) + #define RCC_AHB1RSTR_GPIOGRST (1U << RCC_AHB1RSTR_GPIOGRST_BIT) + #define RCC_AHB1RSTR_GPIOFRST (1U << RCC_AHB1RSTR_GPIOFRST_BIT) + #define RCC_AHB1RSTR_GPIOERST (1U << RCC_AHB1RSTR_GPIOERST_BIT) + #define RCC_AHB1RSTR_GPIODRST (1U << RCC_AHB1RSTR_GPIODRST_BIT) + #define RCC_AHB1RSTR_GPIOCRST (1U << RCC_AHB1RSTR_GPIOCRST_BIT) + #define RCC_AHB1RSTR_GPIOBRST (1U << RCC_AHB1RSTR_GPIOBRST_BIT) + #define RCC_AHB1RSTR_GPIOARST (1U << RCC_AHB1RSTR_GPIOARST_BIT) + + /* AHB2 */ + + #define RCC_AHB2RSTR_OTGFSRST_BIT 7 + #define RCC_AHB2RSTR_RNGRST_BIT 6 + #define RCC_AHB2RSTR_HASHRST_BIT 5 + #define RCC_AHB2RSTR_CRYPRST_BIT 4 + #define RCC_AHB2RSTR_DCMIRST_BIT 0 + + #define RCC_AHB2RSTR_OTGFSRST (1U << RCC_AHB2RSTR_OTGFSRST_BIT) + #define RCC_AHB2RSTR_RNGRST (1U << RCC_AHB2RSTR_RNGRST_BIT) + #define RCC_AHB2RSTR_HASHRST (1U << RCC_AHB2RSTR_HASHRST_BIT) + #define RCC_AHB2RSTR_CRYPRST (1U << RCC_AHB2RSTR_CRYPRST_BIT) + #define RCC_AHB2RSTR_DCMIRST (1U << RCC_AHB2RSTR_DCMIRST_BIT) + + /* AHB3 */ + + #define RCC_AHB3RSTR_FSMCRST_BIT 0 + + #define RCC_AHB3RSTR_FSMCRST (1U << RCC_AHB3RSTR_FSMCRST_BIT) + + /* APB1 */ + + #define RCC_APB1RSTR_DACRST_BIT 29 + #define RCC_APB1RSTR_PWRRST_BIT 28 + #define RCC_APB1RSTR_CAN2RST_BIT 26 + #define RCC_APB1RSTR_CAN1RST_BIT 25 + #define RCC_APB1RSTR_I2C3RST_BIT 23 + #define RCC_APB1RSTR_I2C2RST_BIT 22 + #define RCC_APB1RSTR_I2C1RST_BIT 21 + #define RCC_APB1RSTR_UART5RST_BIT 20 + #define RCC_APB1RSTR_UART4RST_BIT 19 + #define RCC_APB1RSTR_UART3RST_BIT 18 + #define RCC_APB1RSTR_UART2RST_BIT 17 + #define RCC_APB1RSTR_SPI3RST_BIT 15 + #define RCC_APB1RSTR_SPI2RST_BIT 14 + #define RCC_APB1RSTR_WWDGRST_BIT 11 + #define RCC_APB1RSTR_TIM14RST_BIT 8 + #define RCC_APB1RSTR_TIM13RST_BIT 7 + #define RCC_APB1RSTR_TIM12RST_BIT 6 + #define RCC_APB1RSTR_TIM7RST_BIT 5 + #define RCC_APB1RSTR_TIM6RST_BIT 4 + #define RCC_APB1RSTR_TIM5RST_BIT 3 + #define RCC_APB1RSTR_TIM4RST_BIT 2 + #define RCC_APB1RSTR_TIM3RST_BIT 1 + #define RCC_APB1RSTR_TIM2RST_BIT 0 + + #define RCC_APB1RSTR_DACRST (1U << RCC_APB1RSTR_DACRST_BIT) + #define RCC_APB1RSTR_PWRRST (1U << RCC_APB1RSTR_PWRRST_BIT) + #define RCC_APB1RSTR_CAN2RST (1U << RCC_APB1RSTR_CAN2RST_BIT) + #define RCC_APB1RSTR_CAN1RST (1U << RCC_APB1RSTR_CAN1RST_BIT) + #define RCC_APB1RSTR_I2C3RST (1U << RCC_APB1RSTR_I2C3RST_BIT) + #define RCC_APB1RSTR_I2C2RST (1U << RCC_APB1RSTR_I2C2RST_BIT) + #define RCC_APB1RSTR_I2C1RST (1U << RCC_APB1RSTR_I2C1RST_BIT) + #define RCC_APB1RSTR_UART5RST (1U << RCC_APB1RSTR_UART5RST_BIT) + #define RCC_APB1RSTR_UART4RST (1U << RCC_APB1RSTR_UART4RST_BIT) + #define RCC_APB1RSTR_UART3RST (1U << RCC_APB1RSTR_UART3RST_BIT) + #define RCC_APB1RSTR_UART2RST (1U << RCC_APB1RSTR_UART2RST_BIT) + #define RCC_APB1RSTR_SPI3RST (1U << RCC_APB1RSTR_SPI3RST_BIT) + #define RCC_APB1RSTR_SPI2RST (1U << RCC_APB1RSTR_SPI2RST_BIT) + #define RCC_APB1RSTR_WWDGRST (1U << RCC_APB1RSTR_WWDGRST_BIT) + #define RCC_APB1RSTR_TIM14RST (1U << RCC_APB1RSTR_TIM14RST_BIT) + #define RCC_APB1RSTR_TIM13RST (1U << RCC_APB1RSTR_TIM13RST_BIT) + #define RCC_APB1RSTR_TIM12RST (1U << RCC_APB1RSTR_TIM12RST_BIT) + #define RCC_APB1RSTR_TIM7RST (1U << RCC_APB1RSTR_TIM7RST_BIT) + #define RCC_APB1RSTR_TIM6RST (1U << RCC_APB1RSTR_TIM6RST_BIT) + #define RCC_APB1RSTR_TIM5RST (1U << RCC_APB1RSTR_TIM5RST_BIT) + #define RCC_APB1RSTR_TIM4RST (1U << RCC_APB1RSTR_TIM4RST_BIT) + #define RCC_APB1RSTR_TIM3RST (1U << RCC_APB1RSTR_TIM3RST_BIT) + #define RCC_APB1RSTR_TIM2RST (1U << RCC_APB1RSTR_TIM2RST_BIT) + + /* APB2 */ + + #define RCC_APB2RSTR_TIM11RST_BIT 18 + #define RCC_APB2RSTR_TIM10RST_BIT 17 + #define RCC_APB2RSTR_TIM9RST_BIT 16 + #define RCC_APB2RSTR_SYSCFGRST_BIT 14 + #define RCC_APB2RSTR_SPI1RST_BIT 12 + #define RCC_APB2RSTR_SDIORST_BIT 11 + #define RCC_APB2RSTR_ADCRST_BIT 8 + #define RCC_APB2RSTR_USART6RST_BIT 5 + #define RCC_APB2RSTR_USART1RST_BIT 4 + #define RCC_APB2RSTR_TIM8RST_BIT 1 + #define RCC_APB2RSTR_TIM1RST_BIT 0 + + #define RCC_APB2RSTR_TIM11RST (1U << RCC_APB2RSTR_TIM11RST_BIT) + #define RCC_APB2RSTR_TIM10RST (1U << RCC_APB2RSTR_TIM10RST_BIT) + #define RCC_APB2RSTR_TIM9RST (1U << RCC_APB2RSTR_TIM9RST_BIT) + #define RCC_APB2RSTR_SYSCFGRST (1U << RCC_APB2RSTR_SYSCFGRST_BIT) + #define RCC_APB2RSTR_SPI1RST (1U << RCC_APB2RSTR_SPI1RST_BIT) + #define RCC_APB2RSTR_SDIORST (1U << RCC_APB2RSTR_SDIORST_BIT) + #define RCC_APB2RSTR_ADCRST (1U << RCC_APB2RSTR_ADCRST_BIT) + #define RCC_APB2RSTR_USART6RST (1U << RCC_APB2RSTR_USART6RST_BIT) + #define RCC_APB2RSTR_USART1RST (1U << RCC_APB2RSTR_USART1RST_BIT) + #define RCC_APB2RSTR_TIM8RST (1U << RCC_APB2RSTR_TIM8RST_BIT) + #define RCC_APB2RSTR_TIM1RST (1U << RCC_APB2RSTR_TIM1RST_BIT) + +Peripheral clock enable registers ++++++++++++++++++++++++++++++++++ + +:: + + /* AHB1 */ + + #define RCC_AHB1ENR_OTGHSULPIEN_BIT 30 + #define RCC_AHB1ENR_OTGHSEN_BIT 29 + #define RCC_AHB1ENR_ETHMACPTPEN_BIT 28 + #define RCC_AHB1ENR_ETHMACRXEN_BIT 27 + #define RCC_AHB1ENR_ETHMACTXEN_BIT 26 + #define RCC_AHB1ENR_ETHMACEN_BIT 25 + #define RCC_AHB1ENR_DMA2EN_BIT 22 + #define RCC_AHB1ENR_DMA1EN_BIT 21 + #define RCC_AHB1ENR_BKPSRAMEN_BIT 18 + #define RCC_AHB1ENR_CRCEN_BIT 12 + #define RCC_AHB1ENR_GPIOIEN_BIT 8 + #define RCC_AHB1ENR_GPIOHEN_BIT 7 + #define RCC_AHB1ENR_GPIOGEN_BIT 6 + #define RCC_AHB1ENR_GPIOFEN_BIT 5 + #define RCC_AHB1ENR_GPIOEEN_BIT 4 + #define RCC_AHB1ENR_GPIODEN_BIT 3 + #define RCC_AHB1ENR_GPIOCEN_BIT 2 + #define RCC_AHB1ENR_GPIOBEN_BIT 1 + #define RCC_AHB1ENR_GPIOAEN_BIT 0 + + #define RCC_AHB1ENR_OTGHSULPIEN (1U << RCC_AHB1ENR_OTGHSULPIEN_BIT) + #define RCC_AHB1ENR_OTGHSEN (1U << RCC_AHB1ENR_OTGHSEN_BIT) + #define RCC_AHB1ENR_ETHMACPTPEN (1U << RCC_AHB1ENR_ETHMACPTPEN_BIT) + #define RCC_AHB1ENR_ETHMACRXEN (1U << RCC_AHB1ENR_ETHMACRXEN_BIT) + #define RCC_AHB1ENR_ETHMACTXEN (1U << RCC_AHB1ENR_ETHMACTXEN_BIT) + #define RCC_AHB1ENR_ETHMACEN (1U << RCC_AHB1ENR_ETHMACEN_BIT) + #define RCC_AHB1ENR_DMA2EN (1U << RCC_AHB1ENR_DMA2EN_BIT) + #define RCC_AHB1ENR_DMA1EN (1U << RCC_AHB1ENR_DMA1EN_BIT) + #define RCC_AHB1ENR_BKPSRAMEN (1U << RCC_AHB1ENR_BKPSRAMEN_BIT) + #define RCC_AHB1ENR_CRCEN (1U << RCC_AHB1ENR_CRCEN_BIT) + #define RCC_AHB1ENR_GPIOIEN (1U << RCC_AHB1ENR_GPIOIEN_BIT) + #define RCC_AHB1ENR_GPIOHEN (1U << RCC_AHB1ENR_GPIOHEN_BIT) + #define RCC_AHB1ENR_GPIOGEN (1U << RCC_AHB1ENR_GPIOGEN_BIT) + #define RCC_AHB1ENR_GPIOFEN (1U << RCC_AHB1ENR_GPIOFEN_BIT) + #define RCC_AHB1ENR_GPIOEEN (1U << RCC_AHB1ENR_GPIOEEN_BIT) + #define RCC_AHB1ENR_GPIODEN (1U << RCC_AHB1ENR_GPIODEN_BIT) + #define RCC_AHB1ENR_GPIOCEN (1U << RCC_AHB1ENR_GPIOCEN_BIT) + #define RCC_AHB1ENR_GPIOBEN (1U << RCC_AHB1ENR_GPIOBEN_BIT) + #define RCC_AHB1ENR_GPIOAEN (1U << RCC_AHB1ENR_GPIOAEN_BIT) + + /* AHB2 */ + + #define RCC_AHB2ENR_OTGFSEN_BIT 7 + #define RCC_AHB2ENR_RNGEN_BIT 6 + #define RCC_AHB2ENR_HASHEN_BIT 5 + #define RCC_AHB2ENR_CRYPEN_BIT 4 + #define RCC_AHB2ENR_DCMIEN_BIT 0 + + #define RCC_AHB2ENR_OTGFSEN (1U << RCC_AHB2ENR_OTGFSEN_BIT) + #define RCC_AHB2ENR_RNGEN (1U << RCC_AHB2ENR_RNGEN_BIT) + #define RCC_AHB2ENR_HASHEN (1U << RCC_AHB2ENR_HASHEN_BIT) + #define RCC_AHB2ENR_CRYPEN (1U << RCC_AHB2ENR_CRYPEN_BIT) + #define RCC_AHB2ENR_DCMIEN (1U << RCC_AHB2ENR_DCMIEN_BIT) + + /* AHB3 */ + + #define RCC_AHB3ENR_FSMCEN_BIT 0 + + #define RCC_AHB3ENR_FSMCEN (1U << RCC_AHB3ENR_FSMCEN_BIT) + + /* APB1 */ + + #define RCC_APB1ENR_DACEN_BIT 29 + #define RCC_APB1ENR_PWREN_BIT 28 + #define RCC_APB1ENR_CAN2EN_BIT 26 + #define RCC_APB1ENR_CAN1EN_BIT 25 + #define RCC_APB1ENR_I2C3EN_BIT 23 + #define RCC_APB1ENR_I2C2EN_BIT 22 + #define RCC_APB1ENR_I2C1EN_BIT 21 + #define RCC_APB1ENR_UART5EN_BIT 20 + #define RCC_APB1ENR_UART4EN_BIT 19 + #define RCC_APB1ENR_USART3EN_BIT 18 + #define RCC_APB1ENR_USART2EN_BIT 17 + #define RCC_APB1ENR_SPI3EN_BIT 15 + #define RCC_APB1ENR_SPI2EN_BIT 14 + #define RCC_APB1ENR_WWDGEN_BIT 11 + #define RCC_APB1ENR_TIM14EN_BIT 8 + #define RCC_APB1ENR_TIM13EN_BIT 7 + #define RCC_APB1ENR_TIM12EN_BIT 6 + #define RCC_APB1ENR_TIM7EN_BIT 5 + #define RCC_APB1ENR_TIM6EN_BIT 4 + #define RCC_APB1ENR_TIM5EN_BIT 3 + #define RCC_APB1ENR_TIM4EN_BIT 2 + #define RCC_APB1ENR_TIM3EN_BIT 1 + #define RCC_APB1ENR_TIM2EN_BIT 0 + + #define RCC_APB1ENR_DACEN (1U << RCC_APB1ENR_DACEN_BIT) + #define RCC_APB1ENR_PWREN (1U << RCC_APB1ENR_PWREN_BIT) + #define RCC_APB1ENR_CAN2EN (1U << RCC_APB1ENR_CAN2EN_BIT) + #define RCC_APB1ENR_CAN1EN (1U << RCC_APB1ENR_CAN1EN_BIT) + #define RCC_APB1ENR_I2C3EN (1U << RCC_APB1ENR_I2C3EN_BIT) + #define RCC_APB1ENR_I2C2EN (1U << RCC_APB1ENR_I2C2EN_BIT) + #define RCC_APB1ENR_I2C1EN (1U << RCC_APB1ENR_I2C1EN_BIT) + #define RCC_APB1ENR_UART5EN (1U << RCC_APB1ENR_UART5EN_BIT) + #define RCC_APB1ENR_UART4EN (1U << RCC_APB1ENR_UART4EN_BIT) + #define RCC_APB1ENR_USART3EN (1U << RCC_APB1ENR_USART3EN_BIT) + #define RCC_APB1ENR_USART2EN (1U << RCC_APB1ENR_USART2EN_BIT) + #define RCC_APB1ENR_SPI3EN (1U << RCC_APB1ENR_SPI3EN_BIT) + #define RCC_APB1ENR_SPI2EN (1U << RCC_APB1ENR_SPI2EN_BIT) + #define RCC_APB1ENR_WWDGEN (1U << RCC_APB1ENR_WWDGEN_BIT) + #define RCC_APB1ENR_TIM14EN (1U << RCC_APB1ENR_TIM14EN_BIT) + #define RCC_APB1ENR_TIM13EN (1U << RCC_APB1ENR_TIM13EN_BIT) + #define RCC_APB1ENR_TIM12EN (1U << RCC_APB1ENR_TIM12EN_BIT) + #define RCC_APB1ENR_TIM7EN (1U << RCC_APB1ENR_TIM7EN_BIT) + #define RCC_APB1ENR_TIM6EN (1U << RCC_APB1ENR_TIM6EN_BIT) + #define RCC_APB1ENR_TIM5EN (1U << RCC_APB1ENR_TIM5EN_BIT) + #define RCC_APB1ENR_TIM4EN (1U << RCC_APB1ENR_TIM4EN_BIT) + #define RCC_APB1ENR_TIM3EN (1U << RCC_APB1ENR_TIM3EN_BIT) + #define RCC_APB1ENR_TIM2EN (1U << RCC_APB1ENR_TIM2EN_BIT) + + /* APB2 */ + + #define RCC_APB2ENR_TIM11EN_BIT 18 + #define RCC_APB2ENR_TIM10EN_BIT 17 + #define RCC_APB2ENR_TIM9EN_BIT 16 + #define RCC_APB2ENR_SYSCFGEN_BIT 14 + #define RCC_APB2ENR_SPI1EN_BIT 12 + #define RCC_APB2ENR_SDIOEN_BIT 11 + #define RCC_APB2ENR_ADC3EN_BIT 10 + #define RCC_APB2ENR_ADC2EN_BIT 9 + #define RCC_APB2ENR_ADC1EN_BIT 8 + #define RCC_APB2ENR_USART6EN_BIT 5 + #define RCC_APB2ENR_USART1EN_BIT 4 + #define RCC_APB2ENR_TIM8EN_BIT 1 + #define RCC_APB2ENR_TIM1EN_BIT 0 + + #define RCC_APB2ENR_TIM11EN (1U << RCC_APB2ENR_TIM11EN_BIT) + #define RCC_APB2ENR_TIM10EN (1U << RCC_APB2ENR_TIM10EN_BIT) + #define RCC_APB2ENR_TIM9EN (1U << RCC_APB2ENR_TIM9EN_BIT) + #define RCC_APB2ENR_SYSCFGEN (1U << RCC_APB2ENR_SYSCFGEN_BIT) + #define RCC_APB2ENR_SPI1EN (1U << RCC_APB2ENR_SPI1EN_BIT) + #define RCC_APB2ENR_SDIOEN (1U << RCC_APB2ENR_SDIOEN_BIT) + #define RCC_APB2ENR_ADC3EN (1U << RCC_APB2ENR_ADC3EN_BIT) + #define RCC_APB2ENR_ADC2EN (1U << RCC_APB2ENR_ADC2EN_BIT) + #define RCC_APB2ENR_ADC1EN (1U << RCC_APB2ENR_ADC1EN_BIT) + #define RCC_APB2ENR_USART6EN (1U << RCC_APB2ENR_USART6EN_BIT) + #define RCC_APB2ENR_USART1EN (1U << RCC_APB2ENR_USART1EN_BIT) + #define RCC_APB2ENR_TIM8EN (1U << RCC_APB2ENR_TIM8EN_BIT) + #define RCC_APB2ENR_TIM1EN (1U << RCC_APB2ENR_TIM1EN_BIT) + +Peripheral clock enable in low power mode registers ++++++++++++++++++++++++++++++++++++++++++++++++++++ + +:: + + /* AHB1 */ + + #define RCC_AHB1LPENR_OTGHSULPILPEN_BIT 30 + #define RCC_AHB1LPENR_OTGHSLPEN_BIT 29 + #define RCC_AHB1LPENR_ETHMACPTPLPEN_BIT 28 + #define RCC_AHB1LPENR_ETHMACRXLPEN_BIT 27 + #define RCC_AHB1LPENR_ETHMACTXLPEN_BIT 26 + #define RCC_AHB1LPENR_ETHMACLPEN_BIT 25 + #define RCC_AHB1LPENR_DMA2LPEN_BIT 22 + #define RCC_AHB1LPENR_DMA1LPEN_BIT 21 + #define RCC_AHB1LPENR_BKPSRAMLPEN_BIT 18 + #define RCC_AHB1LPENR_SRAM2LPEN_BIT 17 + #define RCC_AHB1LPENR_SRAM1LPEN_BIT 16 + #define RCC_AHB1LPENR_FLITFLPEN_BIT 15 + #define RCC_AHB1LPENR_CRCLPEN_BIT 12 + #define RCC_AHB1LPENR_GPIOILPEN_BIT 8 + #define RCC_AHB1LPENR_GPIOGLPEN_BIT 6 + #define RCC_AHB1LPENR_GPIOFLPEN_BIT 5 + #define RCC_AHB1LPENR_GPIOELPEN_BIT 4 + #define RCC_AHB1LPENR_GPIODLPEN_BIT 3 + #define RCC_AHB1LPENR_GPIOCLPEN_BIT 2 + #define RCC_AHB1LPENR_GPIOBLPEN_BIT 1 + #define RCC_AHB1LPENR_GPIOALPEN_BIT 0 + + #define RCC_AHB1LPENR_OTGHSULPILPEN (1U << RCC_AHB1LPENR_OTGHSULPILPEN_BIT) + #define RCC_AHB1LPENR_OTGHSLPEN (1U << RCC_AHB1LPENR_OTGHSLPEN_BIT) + #define RCC_AHB1LPENR_ETHMACPTPLPEN (1U << RCC_AHB1LPENR_ETHMACPTPLPEN_BIT) + #define RCC_AHB1LPENR_ETHMACRXLPEN (1U << RCC_AHB1LPENR_ETHMACRXLPEN_BIT) + #define RCC_AHB1LPENR_ETHMACTXLPEN (1U << RCC_AHB1LPENR_ETHMACTXLPEN_BIT) + #define RCC_AHB1LPENR_ETHMACLPEN (1U << RCC_AHB1LPENR_ETHMACLPEN_BIT) + #define RCC_AHB1LPENR_DMA2LPEN (1U << RCC_AHB1LPENR_DMA2LPEN_BIT) + #define RCC_AHB1LPENR_DMA1LPEN (1U << RCC_AHB1LPENR_DMA1LPEN_BIT) + #define RCC_AHB1LPENR_BKPSRAMLPEN (1U << RCC_AHB1LPENR_BKPSRAMLPEN_BIT) + #define RCC_AHB1LPENR_SRAM2LPEN (1U << RCC_AHB1LPENR_SRAM2LPEN_BIT) + #define RCC_AHB1LPENR_SRAM1LPEN (1U << RCC_AHB1LPENR_SRAM1LPEN_BIT) + #define RCC_AHB1LPENR_FLITFLPEN (1U << RCC_AHB1LPENR_FLITFLPEN_BIT) + #define RCC_AHB1LPENR_CRCLPEN (1U << RCC_AHB1LPENR_CRCLPEN_BIT) + #define RCC_AHB1LPENR_GPIOILPEN (1U << RCC_AHB1LPENR_GPIOILPEN_BIT) + #define RCC_AHB1LPENR_GPIOGLPEN (1U << RCC_AHB1LPENR_GPIOGLPEN_BIT) + #define RCC_AHB1LPENR_GPIOFLPEN (1U << RCC_AHB1LPENR_GPIOFLPEN_BIT) + #define RCC_AHB1LPENR_GPIOELPEN (1U << RCC_AHB1LPENR_GPIOELPEN_BIT) + #define RCC_AHB1LPENR_GPIODLPEN (1U << RCC_AHB1LPENR_GPIODLPEN_BIT) + #define RCC_AHB1LPENR_GPIOCLPEN (1U << RCC_AHB1LPENR_GPIOCLPEN_BIT) + #define RCC_AHB1LPENR_GPIOBLPEN (1U << RCC_AHB1LPENR_GPIOBLPEN_BIT) + #define RCC_AHB1LPENR_GPIOALPEN (1U << RCC_AHB1LPENR_GPIOALPEN_BIT) + + /* AHB2 */ + + #define RCC_AHB2LPENR_OTGFSLPEN_BIT 7 + #define RCC_AHB2LPENR_RNGLPEN_BIT 6 + #define RCC_AHB2LPENR_HASHLPEN_BIT 5 + #define RCC_AHB2LPENR_CRYPLPEN_BIT 4 + #define RCC_AHB2LPENR_DCMILPEN_BIT 0 + + #define RCC_AHB2LPENR_OTGFSLPEN (1U << RCC_AHB2LPENR_OTGFSLPEN_BIT) + #define RCC_AHB2LPENR_RNGLPEN (1U << RCC_AHB2LPENR_RNGLPEN_BIT) + #define RCC_AHB2LPENR_HASHLPEN (1U << RCC_AHB2LPENR_HASHLPEN_BIT) + #define RCC_AHB2LPENR_CRYPLPEN (1U << RCC_AHB2LPENR_CRYPLPEN_BIT) + #define RCC_AHB2LPENR_DCMILPEN (1U << RCC_AHB2LPENR_DCMILPEN_BIT) + + /* AHB3 */ + + #define RCC_AHB3LPENR_FSMCLPEN_BIT 0 + + #define RCC_AHB3LPENR_FSMCLPEN (1U << RCC_AHB3LPENR_FSMCLPEN_BIT) + + /* APB1 */ + + #define RCC_APB1LPENR_DACLPEN_BIT 29 + #define RCC_APB1LPENR_PWRLPEN_BIT 28 + #define RCC_APB1LPENR_CAN2LPEN_BIT 26 + #define RCC_APB1LPENR_CAN1LPEN_BIT 25 + #define RCC_APB1LPENR_I2C3LPEN_BIT 23 + #define RCC_APB1LPENR_I2C2LPEN_BIT 22 + #define RCC_APB1LPENR_I2C1LPEN_BIT 21 + #define RCC_APB1LPENR_UART5LPEN_BIT 20 + #define RCC_APB1LPENR_UART4LPEN_BIT 19 + #define RCC_APB1LPENR_USART3LPEN_BIT 18 + #define RCC_APB1LPENR_USART2LPEN_BIT 17 + #define RCC_APB1LPENR_SPI3LPEN_BIT 15 + #define RCC_APB1LPENR_SPI2LPEN_BIT 14 + #define RCC_APB1LPENR_WWDGLPEN_BIT 11 + #define RCC_APB1LPENR_TIM14LPEN_BIT 8 + #define RCC_APB1LPENR_TIM13LPEN_BIT 7 + #define RCC_APB1LPENR_TIM12LPEN_BIT 6 + #define RCC_APB1LPENR_TIM7LPEN_BIT 5 + #define RCC_APB1LPENR_TIM6LPEN_BIT 4 + #define RCC_APB1LPENR_TIM5LPEN_BIT 3 + #define RCC_APB1LPENR_TIM4LPEN_BIT 2 + #define RCC_APB1LPENR_TIM3LPEN_BIT 1 + #define RCC_APB1LPENR_TIM2LPEN_BIT 0 + + #define RCC_APB1LPENR_DACLPEN (1U << RCC_APB1LPENR_DACLPEN_BIT) + #define RCC_APB1LPENR_PWRLPEN (1U << RCC_APB1LPENR_PWRLPEN_BIT) + #define RCC_APB1LPENR_CAN2LPEN (1U << RCC_APB1LPENR_CAN2LPEN_BIT) + #define RCC_APB1LPENR_CAN1LPEN (1U << RCC_APB1LPENR_CAN1LPEN_BIT) + #define RCC_APB1LPENR_I2C3LPEN (1U << RCC_APB1LPENR_I2C3LPEN_BIT) + #define RCC_APB1LPENR_I2C2LPEN (1U << RCC_APB1LPENR_I2C2LPEN_BIT) + #define RCC_APB1LPENR_I2C1LPEN (1U << RCC_APB1LPENR_I2C1LPEN_BIT) + #define RCC_APB1LPENR_UART5LPEN (1U << RCC_APB1LPENR_UART5LPEN_BIT) + #define RCC_APB1LPENR_UART4LPEN (1U << RCC_APB1LPENR_UART4LPEN_BIT) + #define RCC_APB1LPENR_USART3LPEN (1U << RCC_APB1LPENR_USART3LPEN_BIT) + #define RCC_APB1LPENR_USART2LPEN (1U << RCC_APB1LPENR_USART2LPEN_BIT) + #define RCC_APB1LPENR_SPI3LPEN (1U << RCC_APB1LPENR_SPI3LPEN_BIT) + #define RCC_APB1LPENR_SPI2LPEN (1U << RCC_APB1LPENR_SPI2LPEN_BIT) + #define RCC_APB1LPENR_WWDGLPEN (1U << RCC_APB1LPENR_WWDGLPEN_BIT) + #define RCC_APB1LPENR_TIM14LPEN (1U << RCC_APB1LPENR_TIM14LPEN_BIT) + #define RCC_APB1LPENR_TIM13LPEN (1U << RCC_APB1LPENR_TIM13LPEN_BIT) + #define RCC_APB1LPENR_TIM12LPEN (1U << RCC_APB1LPENR_TIM12LPEN_BIT) + #define RCC_APB1LPENR_TIM7LPEN (1U << RCC_APB1LPENR_TIM7LPEN_BIT) + #define RCC_APB1LPENR_TIM6LPEN (1U << RCC_APB1LPENR_TIM6LPEN_BIT) + #define RCC_APB1LPENR_TIM5LPEN (1U << RCC_APB1LPENR_TIM5LPEN_BIT) + #define RCC_APB1LPENR_TIM4LPEN (1U << RCC_APB1LPENR_TIM4LPEN_BIT) + #define RCC_APB1LPENR_TIM3LPEN (1U << RCC_APB1LPENR_TIM3LPEN_BIT) + #define RCC_APB1LPENR_TIM2LPEN (1U << RCC_APB1LPENR_TIM2LPEN_BIT) + + /* APB2 */ + + #define RCC_APB2LPENR_TIM11LPEN_BIT 18 + #define RCC_APB2LPENR_TIM10LPEN_BIT 17 + #define RCC_APB2LPENR_TIM9LPEN_BIT 16 + #define RCC_APB2LPENR_SYSCFGLPEN_BIT 14 + #define RCC_APB2LPENR_SPI1LPEN_BIT 12 + #define RCC_APB2LPENR_SDIOLPEN_BIT 11 + #define RCC_APB2LPENR_ADC3LPEN_BIT 10 + #define RCC_APB2LPENR_ADC2LPEN_BIT 9 + #define RCC_APB2LPENR_ADC1LPEN_BIT 8 + #define RCC_APB2LPENR_USART6LPEN_BIT 5 + #define RCC_APB2LPENR_USART1LPEN_BIT 4 + #define RCC_APB2LPENR_TIM8LPEN_BIT 1 + #define RCC_APB2LPENR_TIM1LPEN_BIT 0 + + #define RCC_APB2LPENR_TIM11LPEN (1U << RCC_APB2LPENR_TIM11LPEN_BIT) + #define RCC_APB2LPENR_TIM10LPEN (1U << RCC_APB2LPENR_TIM10LPEN_BIT) + #define RCC_APB2LPENR_TIM9LPEN (1U << RCC_APB2LPENR_TIM9LPEN_BIT) + #define RCC_APB2LPENR_SYSCFGLPEN (1U << RCC_APB2LPENR_SYSCFGLPEN_BIT) + #define RCC_APB2LPENR_SPI1LPEN (1U << RCC_APB2LPENR_SPI1LPEN_BIT) + #define RCC_APB2LPENR_SDIOLPEN (1U << RCC_APB2LPENR_SDIOLPEN_BIT) + #define RCC_APB2LPENR_ADC3LPEN (1U << RCC_APB2LPENR_ADC3LPEN_BIT) + #define RCC_APB2LPENR_ADC2LPEN (1U << RCC_APB2LPENR_ADC2LPEN_BIT) + #define RCC_APB2LPENR_ADC1LPEN (1U << RCC_APB2LPENR_ADC1LPEN_BIT) + #define RCC_APB2LPENR_USART6LPEN (1U << RCC_APB2LPENR_USART6LPEN_BIT) + #define RCC_APB2LPENR_USART1LPEN (1U << RCC_APB2LPENR_USART1LPEN_BIT) + #define RCC_APB2LPENR_TIM8LPEN (1U << RCC_APB2LPENR_TIM8LPEN_BIT) + #define RCC_APB2LPENR_TIM1LPEN (1U << RCC_APB2LPENR_TIM1LPEN_BIT) + +Backup domain control register +++++++++++++++++++++++++++++++ + +:: + + #define RCC_BDCR_BDRST_BIT 16 + #define RCC_BDCR_RTCEN_BIT 15 + #define RCC_BDCR_LSEBYP_BIT 2 + #define RCC_BDCR_LSERDY_BIT 1 + #define RCC_BDCR_LSEON_BIT 0 + + #define RCC_BDCR_BDRST (1U << RCC_BDCR_BDRST_BIT) + #define RCC_BDCR_RTCEN (1U << RCC_BDCR_RTCEN_BIT) + #define RCC_BDCR_RTCSEL (0x3 << 8) + #define RCC_BDCR_RTCSEL_NOCLOCK (0x0 << 8) + #define RCC_BDCR_RTCSEL_LSE (0x1 << 8) + #define RCC_BDCR_RTCSEL_LSI (0x2 << 8) + #define RCC_BDCR_RTCSEL_HSE_DIV (0x3 << 8) + #define RCC_BDCR_LSEBYP (1U << RCC_BDCR_LSEBYP_BIT) + #define RCC_BDCR_LSERDY (1U << RCC_BDCR_LSERDY_BIT) + #define RCC_BDCR_LSEON (1U << RCC_BDCR_LSEON_BIT) + +Clock control and status register ++++++++++++++++++++++++++++++++++ + +:: + + #define RCC_CSR_LPWRRSTF_BIT 31 + #define RCC_CSR_WWDGRSTF_BIT 30 + #define RCC_CSR_IWDGRSTF_BIT 29 + #define RCC_CSR_SFTRSTF_BIT 28 + #define RCC_CSR_PORRSTF_BIT 27 + #define RCC_CSR_PINRSTF_BIT 26 + #define RCC_CSR_BORRSTF_BIT 25 + #define RCC_CSR_RMVF_BIT 24 + #define RCC_CSR_LSIRDY_BIT 1 + #define RCC_CSR_LSION_BIT 0 + + #define RCC_CSR_LPWRRSTF (1U << RCC_CSR_LPWRRSTF_BIT) + #define RCC_CSR_WWDGRSTF (1U << RCC_CSR_WWDGRSTF_BIT) + #define RCC_CSR_IWDGRSTF (1U << RCC_CSR_IWDGRSTF_BIT) + #define RCC_CSR_SFTRSTF (1U << RCC_CSR_SFTRSTF_BIT) + #define RCC_CSR_PORRSTF (1U << RCC_CSR_PORRSTF_BIT) + #define RCC_CSR_PINRSTF (1U << RCC_CSR_PINRSTF_BIT) + #define RCC_CSR_BORRSTF (1U << RCC_CSR_BORRSTF_BIT) + #define RCC_CSR_RMVF (1U << RCC_CSR_RMVF_BIT) + #define RCC_CSR_LSIRDY (1U << RCC_CSR_LSIRDY_BIT) + #define RCC_CSR_LSION (1U << RCC_CSR_LSION_BIT) + +Spread spectrum clock generation register ++++++++++++++++++++++++++++++++++++++++++ + +:: + + #define RCC_SSCGR_SSCGEN_BIT 31 + #define RCC_SSCGR_SPREADSEL_BIT 30 + + #define RCC_SSCGR_SSCGEN (1U << RCC_SSCGR_SSCGEN_BIT) + #define RCC_SSCGR_SPREADSEL (1U << RCC_SSCGR_SPREADSEL_BIT) + #define RCC_SSCGR_SPREADSEL_CENTER (0x0 << RCC_SSCGR_SPREADSEL_BIT) + #define RCC_SSCGR_SPREADSEL_DOWN (0x1 << RCC_SSCGR_SPREADSEL_BIT) + #define RCC_SSCGR_INCSTEP (0xFFF << 16) + #define RCC_SSCGR_MODPER 0xFFFF + +PLLI2S configuration register ++++++++++++++++++++++++++++++ + +:: + + #define RCC_PLLI2SCFGR_PLLI2SR (0x7 << 28) + #define RCC_PLLI2SCFGR_PLLI2SN (0x1FF << 6) + diff --git a/docs/source/libmaple/api/rcc.rst b/docs/source/libmaple/api/rcc.rst new file mode 100644 index 0000000..ce58ec8 --- /dev/null +++ b/docs/source/libmaple/api/rcc.rst @@ -0,0 +1,360 @@ +.. highlight:: c +.. _libmaple-rcc: + +``<libmaple/rcc.h>`` +==================== + +Reset and Clock Control (RCC) support. + +The RCC is responsible for managing the MCU's various clocks. This +includes the core clock SYSCLK, which determines the CPU clock +frequency, as well as the clock lines that drive peripherals. + +Because of this, the available RCC functionality varies by target. +There are a :ref:`variety of abstractions <libmaple-rcc-core-types>` +in place to make managing this more convenient. + +.. contents:: Contents + :local: + :depth: 2 + +.. _libmaple-rcc-core-types: + +Core Types +---------- + +The core abstractions in place are +:ref:`rcc_clk_id <libmaple-rcc-rcc_clk_id>`, +:ref:`rcc_clk <libmaple-rcc-rcc_clk>`, +:ref:`rcc_sysclk_src <libmaple-rcc-rcc_sysclk_src>`, +:ref:`rcc_clk_domain <libmaple-rcc-rcc_clk_domain>`, and +:ref:`rcc_prescaler <libmaple-rcc-rcc_prescaler>`. + +.. _libmaple-rcc-rcc_clk_id: + +Peripheral Identifiers: ``rcc_clk_id`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +``rcc_clk_id`` is an enum used to identify peripherals. The RCC +back-ends use them to look up a peripheral's bus and clock line, but +they are also generally useful as unique identifiers for each +peripheral. You can manage peripherals using their ``rcc_clk_id``\ s +with :ref:`these functions <libmaple-rcc-clk-id-funcs>`. + +Peripherals which are common across targets have the same token +(though not necessarily the same value) for their ``rcc_clk_id`` +across different targets. For example, the ``rcc_clk_id`` for the ADC1 +peripheral is always ``RCC_ADC1`` regardless of the target. +Additionally, as explained in :ref:`libmaple-overview-devices`, each +peripheral device type struct contains the ``rcc_clk_id`` for that +peripheral in a ``clk_id`` field. + +The available ``rcc_clk_id``\ s on each supported target series are as +follows. + +STM32F1 Targets ++++++++++++++++ + +.. doxygenenum:: stm32f1::rcc_clk_id + +STM32F2 Targets ++++++++++++++++ + +.. doxygenenum:: stm32f2::rcc_clk_id + +.. _libmaple-rcc-rcc_sysclk_src: + +System Clock (SYSCLK) Sources: ``rcc_sysclk_src`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +SYSCLK is the core system clock. It determines the CPU clock rate, and +it's the base clock which is used to drive (most of) the peripherals +on the STM32. ``rcc_sysclk_src`` is an enum for the possible SYSCLK +sources. Switch the SYSCLK source with :ref:`rcc_switch_sysclk() +<libmaple-rcc-rcc_switch_sysclk>`. + +.. doxygenenum:: rcc_sysclk_src + +As a special case, you can configure the PLL with a call to +:ref:`rcc_configure_pll() <libmaple-rcc-rcc_configure_pll>`. + +.. _libmaple-rcc-rcc_clk: + +System and Secondary Clock Sources: ``rcc_clk`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The ``rcc_clk`` type gives available system and secondary clock +sources (e.g. HSI, HSE, LSE). As with :ref:`rcc_clk_id +<libmaple-rcc-rcc_clk_id>`, clock sources which are common across +targets have the same token, but not necessarily the same value, for +their ``rcc_clk`` on each target. A variety of :ref:`clock management +functions <libmaple-rcc-clk-funcs>` are available. + +Note that the inclusion of secondary clock sources, like LSI and LSE, +makes ``rcc_clk`` different from the SYSCLK sources, which are managed +using :ref:`rcc_sysclk_src <libmaple-rcc-rcc_sysclk_src>`. + +The available ``rcc_clk``\ s for each supported target series are as +follows. + +STM32F1 Targets ++++++++++++++++ + +.. doxygenenum:: stm32f1::rcc_clk + +STM32F2 Targets ++++++++++++++++ + +.. doxygenenum:: stm32f2::rcc_clk + +.. _libmaple-rcc-rcc_clk_domain: + +Clock Domains: ``rcc_clk_domain`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +These specify the available clock domains. For example, each AHB and +APB is a clock domain. + +This type mostly exists to enable asking devices what bus they're on, +which, given knowledge of your system's clock configuration, can be +useful when making decisions about prescalers, etc. + +Given an :ref:`rcc_clk_id <libmaple-rcc-rcc_clk_id>`, you can get the +peripheral's clock domain with :ref:`rcc_dev_clk() +<libmaple-rcc-rcc_dev_clk>`. Clock domains that are common across +series have the same token (but not necessarily the same value) for +their corresponding ``rcc_clk_domain``. + +The available ``rcc_clk_domain``\ s for each supported target series +are as follows. + +STM32F1 Targets ++++++++++++++++ + +.. doxygenenum:: stm32f1::rcc_clk_domain + +STM32F2 Targets ++++++++++++++++ + +.. doxygenenum:: stm32f2::rcc_clk_domain + +.. _libmaple-rcc-rcc_prescaler: + +Prescalers: ``rcc_prescaler`` and Friends +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Available prescalers are managed via the ``rcc_prescaler`` type, the +``rcc_set_prescaler()`` function, and a variety of related prescaler +divider types. See :ref:`libmaple-rcc-prescalers` for more +information and usage notes. + +Functions +--------- + +.. _libmaple-rcc-sysclk-funcs: +.. _libmaple-rcc-rcc_switch_sysclk: + +SYSCLK Management +~~~~~~~~~~~~~~~~~ + +Change the SYSCLK source with ``rcc_switch_sysclk()``. + +.. doxygenfunction:: rcc_switch_sysclk + +.. _libmaple-rcc-rcc_configure_pll: + +PLL Configuration +~~~~~~~~~~~~~~~~~ + +You can configure the PLL with ``rcc_configure_pll()``. This takes an +``rcc_pll_cfg`` struct as its argument. Though the definition of +``rcc_pll_cfg`` is common across series, its contents are entirely +target-dependent. + +.. doxygenstruct:: rcc_pll_cfg +.. _rcc-rcc_configure_pll: +.. doxygenfunction:: rcc_configure_pll + +The fields in an ``rcc_pll_cfg`` on each target are as follows. + +rcc_pll_cfg on STM32F1 Targets +++++++++++++++++++++++++++++++ + +The ``pllsrc`` field is chosen from the following. + +.. doxygenenum:: stm32f1::rcc_pllsrc + +.. FIXME [0.0.13] We've got plans to redo this; make sure you watch +.. libmaple for changes here. + +The ``data`` field must point to a ``struct stm32f1_rcc_pll_data``. +This just contains an ``rcc_pll_multiplier``. + +.. doxygenenum:: stm32f1::rcc_pll_multiplier + +.. doxygenstruct:: stm32f1::stm32f1_rcc_pll_data + +rcc_pll_cfg on STM32F2 Targets +++++++++++++++++++++++++++++++ + +The ``pllsrc`` field is chosen from the following. + +.. doxygenenum:: stm32f2::rcc_pllsrc + +The ``data`` field must point to a ``struct stm32f2_rcc_pll_data``. + +.. doxygenstruct:: stm32f2::stm32f2_rcc_pll_data + +.. _libmaple-rcc-clk-funcs: + +System and Secondary Clock Management +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +These functions are useful for managing clocks via their :ref:`rcc_clk +<libmaple-rcc-rcc_clk>`. + +.. doxygenfunction:: rcc_turn_on_clk +.. doxygenfunction:: rcc_turn_off_clk +.. doxygenfunction:: rcc_is_clk_on +.. doxygenfunction:: rcc_is_clk_ready + +.. _libmaple-rcc-clk-id-funcs: + +Peripheral Management +~~~~~~~~~~~~~~~~~~~~~ + +These functions are useful for managing peripherals via their +:ref:`rcc_clk_id <libmaple-rcc-rcc_clk_id>`. + +.. _libmaple-rcc-rcc_clk_enable: +.. doxygenfunction:: rcc_clk_enable +.. doxygenfunction:: rcc_reset_dev +.. _libmaple-rcc-rcc_dev_clk: +.. doxygenfunction:: rcc_dev_clk + +.. _libmaple-rcc-prescalers: + +Prescaler Management +~~~~~~~~~~~~~~~~~~~~ + +All clock prescalers managed by RCC can be controlled with a single +function, ``rcc_set_prescaler()``. + +.. doxygenfunction:: rcc_set_prescaler + +The arguments to ``rcc_set_prescaler()`` are target-dependent, but +follow a common pattern: + +- The first argument is the prescaler to set, so there's one for each + peripheral clock domain, etc. These have names like + ``RCC_PRESCALER_FOO``, e.g. ``RCC_PRESCALER_APB1``. Choose the + prescaler from the ``rcc_prescaler``\ s on your target (see below). + +- The second argument is the actual clock divider to use; it's chosen + based on the first argument. The dividers for ``RCC_PRESCALER_FOO`` + are given by the type ``rcc_foo_divider``, and have values like + ``RCC_FOO_xxx_DIV_y``. This means that the foo clock will be the + ``xxx`` clock divided by ``y``. + +For example, calling ``rcc_set_prescaler(RCC_PRESCALER_APB1, +RCC_APB1_HCLK_DIV_1)`` would set the APB1 clock to HCLK divided by 1. + +Prescalers which are common across targets have the same token, though +not necessarily the same value, for their ``rcc_prescaler`` (for +example, ``RCC_PRESCALER_APB1`` is available on both STM32F1 and +STM32F2 targets). The available prescalers and dividers on each +supported target series are as follows. + +STM32F1 Targets ++++++++++++++++ + +.. doxygenenum:: stm32f1::rcc_prescaler +.. doxygenenum:: stm32f1::rcc_adc_divider +.. doxygenenum:: stm32f1::rcc_apb1_divider +.. doxygenenum:: stm32f1::rcc_apb2_divider +.. doxygenenum:: stm32f1::rcc_ahb_divider + +STM32F2 Targets ++++++++++++++++ + +.. doxygenenum:: stm32f2::rcc_prescaler +.. doxygenenum:: stm32f2::rcc_mco2_divider +.. doxygenenum:: stm32f2::rcc_mco1_divider +.. doxygenenum:: stm32f2::rcc_rtc_divider +.. doxygenenum:: stm32f2::rcc_apb2_divider +.. doxygenenum:: stm32f2::rcc_apb1_divider +.. doxygenenum:: stm32f2::rcc_ahb_divider + +Register Maps +------------- + +These vary by target. The base pointer is always ``RCC_BASE``. + +.. doxygendefine:: RCC_BASE + +STM32F1 Targets +~~~~~~~~~~~~~~~ + +.. doxygenstruct:: stm32f1::rcc_reg_map + +STM32F2 Targets +~~~~~~~~~~~~~~~ + +.. doxygenstruct:: stm32f2::rcc_reg_map + +Register Bit Definitions +------------------------ + +These are given as source code. Available register bit definitions +vary by target. + +.. We need this include to avoid crashing Emacs's ReST parser. Yuck. + +.. include:: rcc-reg-bits.txt + +Deprecated Functionality +------------------------ + +.. _rcc-rcc_clk_init: +.. doxygenfunction:: stm32f1::rcc_clk_init + +To replace a call to ``rcc_clk_init()`` in order to set SYSCLK to PLL +driven by an external oscillator, you can use something like this, +which is portable except for the initialization of ``your_pll_cfg``:: + + /* You need to make this point to something valid for your target; see + * the documentation for rcc_configure_pll() for more details. */ + extern rcc_pll_cfg *your_pll_cfg; + + void pll_reconfigure() { + /* Turn on HSI using rcc_turn_on_clk() and wait for it to + * become ready by busy-waiting on rcc_is_clk_ready(). + * + * Switch to HSI to ensure we're not using the PLL while we + * reconfigure it. */ + rcc_turn_on_clk(RCC_CLK_HSI); + while (!rcc_is_clk_ready(RCC_CLK_HSI)) + ; + rcc_switch_sysclk(RCC_CLKSRC_HSI); + + /* Turn off HSE and the PLL, or we can't reconfigure it. */ + rcc_turn_off_clk(RCC_CLK_PLL); + rcc_turn_off_clk(RCC_CLK_HSE); + + /* Reconfigure the PLL. You can also perform any other + * prescaler management here. */ + rcc_configure_pll(your_pll_cfg); + + /* Turn on RCC_CLK_HSE. */ + rcc_turn_on_clk(RCC_CLK_HSE); + while (!rcc_is_clk_ready(RCC_CLK_HSE)) + ; + + /* Turn on RCC_CLK_PLL. */ + rcc_turn_on_clk(RCC_CLK_PLL); + while (!rcc_is_clk_ready(RCC_CLK_PLL)) + ; + + /* Finally, switch to the PLL. */ + rcc_switch_sysclk(RCC_CLKSRC_PLL); + } diff --git a/docs/source/libmaple/api/ring_buffer.rst b/docs/source/libmaple/api/ring_buffer.rst new file mode 100644 index 0000000..ef082dd --- /dev/null +++ b/docs/source/libmaple/api/ring_buffer.rst @@ -0,0 +1,27 @@ +.. highlight:: c +.. _libmaple-ring_buffer: + +``<libmaple/ring_buffer.h>`` +============================ + +Simple circular byte buffer. This implementation is not thread-safe. +In particular, none of these functions is guaranteed to be re-entrant. + +Ring Buffer Type +---------------- + +.. doxygenstruct:: ring_buffer + +Ring Buffer Operations +---------------------- + +.. doxygenfunction:: rb_init +.. doxygenfunction:: rb_full_count +.. doxygenfunction:: rb_is_full +.. doxygenfunction:: rb_is_empty +.. doxygenfunction:: rb_insert +.. doxygenfunction:: rb_remove +.. doxygenfunction:: rb_safe_remove +.. doxygenfunction:: rb_safe_insert +.. doxygenfunction:: rb_push_insert +.. doxygenfunction:: rb_reset diff --git a/docs/source/libmaple/api/scb.rst b/docs/source/libmaple/api/scb.rst new file mode 100644 index 0000000..96d464f --- /dev/null +++ b/docs/source/libmaple/api/scb.rst @@ -0,0 +1,156 @@ +.. highlight:: c +.. _libmaple-scb: + +``<libmaple/scb.h>`` +==================== + +.. TODO [0.0.13] check for any F2 modifications + +System Control Block (SCB) support. This is currently limited to a +register map and bit definitions. + +.. warning:: + + At time of writing, ST PM0056 (which specifies the system control + block on STM32F1) appears to be buggy (some registers required or + specified as implementation-defined by ARM are not mentioned). + This file is the result of combining material from ARM and ST, and + is subject to change. See the source code for more details. + + If you notice a problem or have any other input on this, please + `contact`_ us! + +.. contents:: Contents + :local: + +Register Maps +------------- + +The SCB has the following register map. Its base pointer is ``SCB_BASE``. + +.. doxygenstruct:: scb_reg_map +.. doxygendefine:: SCB_BASE + +Register Bit Definitions +------------------------ + +These are given as source code. + +:: + + /* No SCB_REG_FIELD_BIT macros as the relevant addresses are not in a + * bit-band region. */ + + /* CPUID base register (SCB_CPUID) */ + + #define SCB_CPUID_IMPLEMENTER (0xFF << 24) + #define SCB_CPUID_VARIANT (0xF << 20) + #define SCB_CPUID_CONSTANT (0xF << 16) + #define SCB_CPUID_PARTNO (0xFFF << 4) + #define SCB_CPUID_REVISION 0xF + + /* Interrupt control state register (SCB_ICSR) */ + + #define SCB_ICSR_NMIPENDSET (1U << 31) + #define SCB_ICSR_PENDSVSET (1U << 28) + #define SCB_ICSR_PENDSVCLR (1U << 27) + #define SCB_ICSR_PENDSTSET (1U << 26) + #define SCB_ICSR_PENDSTCLR (1U << 25) + #define SCB_ICSR_ISRPENDING (1U << 22) + #define SCB_ICSR_VECTPENDING (0x3FF << 12) + #define SCB_ICSR_RETOBASE (1U << 11) + #define SCB_ICSR_VECTACTIVE 0xFF + + /* Vector table offset register (SCB_VTOR) */ + + #define SCB_VTOR_TBLOFF (0x1FFFFF << 9) + + /* Application interrupt and reset control register (SCB_AIRCR) */ + + #define SCB_AIRCR_VECTKEYSTAT (0x5FA << 16) + #define SCB_AIRCR_VECTKEY (0x5FA << 16) + #define SCB_AIRCR_ENDIANNESS (1U << 15) + #define SCB_AIRCR_PRIGROUP (0x3 << 8) + #define SCB_AIRCR_SYSRESETREQ (1U << 2) + #define SCB_AIRCR_VECTCLRACTIVE (1U << 1) + #define SCB_AIRCR_VECTRESET (1U << 0) + + /* System control register (SCB_SCR) */ + + #define SCB_SCR_SEVONPEND (1U << 4) + #define SCB_SCR_SLEEPDEEP (1U << 2) + #define SCB_SCR_SLEEPONEXIT (1U << 1) + + /* Configuration and Control Register (SCB_CCR) */ + + #define SCB_CCR_STKALIGN (1U << 9) + #define SCB_CCR_BFHFNMIGN (1U << 8) + #define SCB_CCR_DIV_0_TRP (1U << 4) + #define SCB_CCR_UNALIGN_TRP (1U << 3) + #define SCB_CCR_USERSETMPEND (1U << 1) + #define SCB_CCR_NONBASETHRDENA (1U << 0) + + /* System handler priority registers (SCB_SHPRx) */ + + #define SCB_SHPR1_PRI6 (0xFF << 16) + #define SCB_SHPR1_PRI5 (0xFF << 8) + #define SCB_SHPR1_PRI4 0xFF + + #define SCB_SHPR2_PRI11 (0xFF << 24) + + #define SCB_SHPR3_PRI15 (0xFF << 24) + #define SCB_SHPR3_PRI14 (0xFF << 16) + + /* System Handler Control and state register (SCB_SHCSR) */ + + #define SCB_SHCSR_USGFAULTENA (1U << 18) + #define SCB_SHCSR_BUSFAULTENA (1U << 17) + #define SCB_SHCSR_MEMFAULTENA (1U << 16) + #define SCB_SHCSR_SVCALLPENDED (1U << 15) + #define SCB_SHCSR_BUSFAULTPENDED (1U << 14) + #define SCB_SHCSR_MEMFAULTPENDED (1U << 13) + #define SCB_SHCSR_USGFAULTPENDED (1U << 12) + #define SCB_SHCSR_SYSTICKACT (1U << 11) + #define SCB_SHCSR_PENDSVACT (1U << 10) + #define SCB_SHCSR_MONITORACT (1U << 8) + #define SCB_SHCSR_SVCALLACT (1U << 7) + #define SCB_SHCSR_USGFAULTACT (1U << 3) + #define SCB_SHCSR_BUSFAULTACT (1U << 1) + #define SCB_SHCSR_MEMFAULTACT (1U << 0) + + /* Configurable fault status register (SCB_CFSR) */ + + #define SCB_CFSR_DIVBYZERO (1U << 25) + #define SCB_CFSR_UNALIGNED (1U << 24) + #define SCB_CFSR_NOCP (1U << 19) + #define SCB_CFSR_INVPC (1U << 18) + #define SCB_CFSR_INVSTATE (1U << 17) + #define SCB_CFSR_UNDEFINSTR (1U << 16) + #define SCB_CFSR_BFARVALID (1U << 15) + #define SCB_CFSR_STKERR (1U << 12) + #define SCB_CFSR_UNSTKERR (1U << 11) + #define SCB_CFSR_IMPRECISERR (1U << 10) + #define SCB_CFSR_PRECISERR (1U << 9) + #define SCB_CFSR_IBUSERR (1U << 8) + #define SCB_CFSR_MMARVALID (1U << 7) + #define SCB_CFSR_MSTKERR (1U << 4) + #define SCB_CFSR_MUNSTKERR (1U << 3) + #define SCB_CFSR_DACCVIOL (1U << 1) + #define SCB_CFSR_IACCVIOL (1U << 0) + + /* Hard Fault Status Register (SCB_HFSR) */ + + #define SCB_HFSR_DEBUG_VT (1U << 31) + #define SCB_CFSR_FORCED (1U << 30) + #define SCB_CFSR_VECTTBL (1U << 1) + + /* Debug Fault Status Register */ + + /* Not specified by PM0056, but required by ARM. The bit definitions + * here are based on the names given in the ARM v7-M ARM. */ + + #define SCB_DFSR_EXTERNAL (1U << 4) + #define SCB_DFSR_VCATCH (1U << 3) + #define SCB_DFSR_DWTTRAP (1U << 2) + #define SCB_DFSR_BKPT (1U << 1) + #define SCB_DFSR_HALTED (1U << 0) diff --git a/docs/source/libmaple/api/spi.rst b/docs/source/libmaple/api/spi.rst new file mode 100644 index 0000000..e72696b --- /dev/null +++ b/docs/source/libmaple/api/spi.rst @@ -0,0 +1,187 @@ +.. highlight:: c +.. _libmaple-spi: + +``spi.h`` +========= + +Serial Peripheral Interface (SPI) support. Currently, there is no I2S +support beyond register bit definitions. + +.. contents:: Contents + :local: + +Types +----- + +.. doxygenstruct:: spi_reg_map +.. doxygenstruct:: spi_dev +.. doxygenenum:: spi_mode +.. doxygenenum:: spi_baud_rate +.. doxygenenum:: spi_cfg_flag +.. doxygenenum:: spi_interrupt + +Devices +------- + +.. doxygenvariable:: SPI1 +.. doxygenvariable:: SPI2 +.. doxygenvariable:: SPI3 + +Functions +--------- + +.. doxygenfunction:: spi_init +.. doxygenfunction:: spi_gpio_cfg +.. doxygenfunction:: spi_master_enable +.. doxygenfunction:: spi_slave_enable +.. doxygenfunction:: spi_tx +.. doxygenfunction:: spi_foreach +.. doxygenfunction:: spi_peripheral_enable +.. doxygenfunction:: spi_peripheral_disable +.. doxygenfunction:: spi_peripheral_disable_all +.. doxygenfunction:: spi_tx_dma_enable +.. doxygenfunction:: spi_tx_dma_disable +.. doxygenfunction:: spi_rx_dma_enable +.. doxygenfunction:: spi_rx_dma_disable +.. doxygenfunction:: spi_is_enabled +.. doxygenfunction:: spi_irq_enable +.. doxygenfunction:: spi_irq_disable +.. doxygenfunction:: spi_dff +.. doxygenfunction:: spi_is_rx_nonempty +.. doxygenfunction:: spi_rx_reg +.. doxygenfunction:: spi_is_tx_empty +.. doxygenfunction:: spi_tx_reg +.. doxygenfunction:: spi_is_busy + +Register Map Base Pointers +-------------------------- + +.. doxygendefine:: SPI1_BASE +.. doxygendefine:: SPI2_BASE +.. doxygendefine:: SPI3_BASE + +Register Bit Definitions +------------------------ + +Control register 1 +~~~~~~~~~~~~~~~~~~ + +.. doxygendefine:: SPI_CR1_BIDIMODE_BIT +.. doxygendefine:: SPI_CR1_BIDIOE_BIT +.. doxygendefine:: SPI_CR1_CRCEN_BIT +.. doxygendefine:: SPI_CR1_CRCNEXT_BIT +.. doxygendefine:: SPI_CR1_DFF_BIT +.. doxygendefine:: SPI_CR1_RXONLY_BIT +.. doxygendefine:: SPI_CR1_SSM_BIT +.. doxygendefine:: SPI_CR1_SSI_BIT +.. doxygendefine:: SPI_CR1_LSBFIRST_BIT +.. doxygendefine:: SPI_CR1_SPE_BIT +.. doxygendefine:: SPI_CR1_MSTR_BIT +.. doxygendefine:: SPI_CR1_CPOL_BIT +.. doxygendefine:: SPI_CR1_CPHA_BIT + +.. doxygendefine:: SPI_CR1_BIDIMODE +.. doxygendefine:: SPI_CR1_BIDIMODE_2_LINE +.. doxygendefine:: SPI_CR1_BIDIMODE_1_LINE +.. doxygendefine:: SPI_CR1_BIDIOE +.. doxygendefine:: SPI_CR1_CRCEN +.. doxygendefine:: SPI_CR1_CRCNEXT +.. doxygendefine:: SPI_CR1_DFF +.. doxygendefine:: SPI_CR1_DFF_8_BIT +.. doxygendefine:: SPI_CR1_DFF_16_BIT +.. doxygendefine:: SPI_CR1_RXONLY +.. doxygendefine:: SPI_CR1_SSM +.. doxygendefine:: SPI_CR1_SSI +.. doxygendefine:: SPI_CR1_LSBFIRST +.. doxygendefine:: SPI_CR1_SPE +.. doxygendefine:: SPI_CR1_BR +.. doxygendefine:: SPI_CR1_BR_PCLK_DIV_2 +.. doxygendefine:: SPI_CR1_BR_PCLK_DIV_4 +.. doxygendefine:: SPI_CR1_BR_PCLK_DIV_8 +.. doxygendefine:: SPI_CR1_BR_PCLK_DIV_16 +.. doxygendefine:: SPI_CR1_BR_PCLK_DIV_32 +.. doxygendefine:: SPI_CR1_BR_PCLK_DIV_64 +.. doxygendefine:: SPI_CR1_BR_PCLK_DIV_128 +.. doxygendefine:: SPI_CR1_BR_PCLK_DIV_256 +.. doxygendefine:: SPI_CR1_MSTR +.. doxygendefine:: SPI_CR1_CPOL +.. doxygendefine:: SPI_CR1_CPOL_LOW +.. doxygendefine:: SPI_CR1_CPOL_HIGH +.. doxygendefine:: SPI_CR1_CPHA + +Control register 2 +~~~~~~~~~~~~~~~~~~ + +.. doxygendefine:: SPI_CR2_TXEIE_BIT +.. doxygendefine:: SPI_CR2_RXNEIE_BIT +.. doxygendefine:: SPI_CR2_ERRIE_BIT +.. doxygendefine:: SPI_CR2_SSOE_BIT +.. doxygendefine:: SPI_CR2_TXDMAEN_BIT +.. doxygendefine:: SPI_CR2_RXDMAEN_BIT + +.. doxygendefine:: SPI_CR2_TXEIE +.. doxygendefine:: SPI_CR2_RXNEIE +.. doxygendefine:: SPI_CR2_ERRIE +.. doxygendefine:: SPI_CR2_SSOE +.. doxygendefine:: SPI_CR2_TXDMAEN +.. doxygendefine:: SPI_CR2_RXDMAEN + +Status register +~~~~~~~~~~~~~~~ + +.. doxygendefine:: SPI_SR_BSY_BIT +.. doxygendefine:: SPI_SR_OVR_BIT +.. doxygendefine:: SPI_SR_MODF_BIT +.. doxygendefine:: SPI_SR_CRCERR_BIT +.. doxygendefine:: SPI_SR_UDR_BIT +.. doxygendefine:: SPI_SR_CHSIDE_BIT +.. doxygendefine:: SPI_SR_TXE_BIT +.. doxygendefine:: SPI_SR_RXNE_BIT + +.. doxygendefine:: SPI_SR_BSY +.. doxygendefine:: SPI_SR_OVR +.. doxygendefine:: SPI_SR_MODF +.. doxygendefine:: SPI_SR_CRCERR +.. doxygendefine:: SPI_SR_UDR +.. doxygendefine:: SPI_SR_CHSIDE +.. doxygendefine:: SPI_SR_CHSIDE_LEFT +.. doxygendefine:: SPI_SR_CHSIDE_RIGHT +.. doxygendefine:: SPI_SR_TXE +.. doxygendefine:: SPI_SR_RXNE + +I2S configuration register +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. doxygendefine:: SPI_I2SCFGR_I2SMOD_BIT +.. doxygendefine:: SPI_I2SCFGR_I2SE_BIT +.. doxygendefine:: SPI_I2SCFGR_PCMSYNC_BIT +.. doxygendefine:: SPI_I2SCFGR_CKPOL_BIT +.. doxygendefine:: SPI_I2SCFGR_CHLEN_BIT + +.. doxygendefine:: SPI_I2SCFGR_I2SMOD +.. doxygendefine:: SPI_I2SCFGR_I2SMOD_SPI +.. doxygendefine:: SPI_I2SCFGR_I2SMOD_I2S +.. doxygendefine:: SPI_I2SCFGR_I2SE +.. doxygendefine:: SPI_I2SCFGR_I2SCFG +.. doxygendefine:: SPI_I2SCFGR_I2SCFG_SLAVE_TX +.. doxygendefine:: SPI_I2SCFGR_I2SCFG_SLAVE_RX +.. doxygendefine:: SPI_I2SCFGR_I2SCFG_MASTER_TX +.. doxygendefine:: SPI_I2SCFGR_I2SCFG_MASTER_RX +.. doxygendefine:: SPI_I2SCFGR_PCMSYNC +.. doxygendefine:: SPI_I2SCFGR_PCMSYNC_SHORT +.. doxygendefine:: SPI_I2SCFGR_PCMSYNC_LONG +.. doxygendefine:: SPI_I2SCFGR_I2SSTD +.. doxygendefine:: SPI_I2SCFGR_I2SSTD_PHILLIPS +.. doxygendefine:: SPI_I2SCFGR_I2SSTD_MSB +.. doxygendefine:: SPI_I2SCFGR_I2SSTD_LSB +.. doxygendefine:: SPI_I2SCFGR_I2SSTD_PCM +.. doxygendefine:: SPI_I2SCFGR_CKPOL +.. doxygendefine:: SPI_I2SCFGR_CKPOL_LOW +.. doxygendefine:: SPI_I2SCFGR_CKPOL_HIGH +.. doxygendefine:: SPI_I2SCFGR_DATLEN +.. doxygendefine:: SPI_I2SCFGR_DATLEN_16_BIT +.. doxygendefine:: SPI_I2SCFGR_DATLEN_24_BIT +.. doxygendefine:: SPI_I2SCFGR_DATLEN_32_BIT +.. doxygendefine:: SPI_I2SCFGR_CHLEN +.. doxygendefine:: SPI_I2SCFGR_CHLEN_16_BIT +.. doxygendefine:: SPI_I2SCFGR_CHLEN_32_BIT diff --git a/docs/source/libmaple/api/stm32.rst b/docs/source/libmaple/api/stm32.rst new file mode 100644 index 0000000..335bda4 --- /dev/null +++ b/docs/source/libmaple/api/stm32.rst @@ -0,0 +1,121 @@ +.. highlight:: c +.. _libmaple-stm32: + +``<libmaple/stm32.h>`` +====================== + +STM32 chip header. This header supplies various series-specific and +chip-specific macros for the current build target. It's useful both +to abstract away hardware details (e.g. through use of +:ref:`STM32_NR_INTERRUPTS <libmaple-stm32-STM32_NR_INTERRUPTS>`) and +to decide what to do when you want something nonportable (e.g. by +checking :ref:`STM32_MCU_SERIES <libmaple-stm32-STM32_MCU_SERIES>`). + +.. contents:: Contents + :local: + +Determining the Target Series +----------------------------- + +The STM32 series (e.g. STM32F1, STM32F2, etc.) of the current target +can be inspected with ``STM32_MCU_SERIES``. + +.. _libmaple-stm32-STM32_MCU_SERIES: +.. doxygendefine:: STM32_MCU_SERIES + +Allowed values for ``STM32_MCU_SERIES`` are the following. This set is +expected to grow over time. + +.. doxygendefine:: STM32_SERIES_F1 +.. doxygendefine:: STM32_SERIES_F2 +.. doxygendefine:: STM32_SERIES_L1 +.. doxygendefine:: STM32_SERIES_F4 + +Series-Specific Characteristics +------------------------------- + +The macros in this section are only available on some STM32 series. + +STM32F1 +~~~~~~~ + +.. note:: These macros are only available when the current target is + an STM32F1 series MCU (i.e., when :ref:`STM32_MCU_SERIES + <libmaple-stm32-STM32_MCU_SERIES>` is ``STM32_SERIES_F1``). + +The STM32F1 series is further subdivided into :ref:`lines +<stm32-series-f1-lines>`. The line of the current target can be +inspected with ``STM32_F1_LINE``. + +.. doxygendefine:: STM32_F1_LINE + +There are five STM32F1 lines. The corresponding values +``STM32_F1_LINE`` can take are the following, though libmaple doesn't +currently support all of them. + +.. doxygendefine:: STM32_F1_LINE_VALUE +.. doxygendefine:: STM32_F1_LINE_ACCESS +.. doxygendefine:: STM32_F1_LINE_USB_ACCESS +.. doxygendefine:: STM32_F1_LINE_PERFORMANCE +.. doxygendefine:: STM32_F1_LINE_CONNECTIVITY + +MCU Feature Tests +----------------- + +The following defines can be used to determine if the target MCU has +a particular feature. + +.. _libmaple-stm32-STM32_HAVE_FSMC: +.. doxygendefine:: STM32_HAVE_FSMC +.. doxygendefine:: STM32_HAVE_USB + +MCU Characteristics +------------------- + +The following defines give salient characteristics of the target MCU. + +.. doxygendefine:: STM32_NR_GPIO_PORTS +.. _libmaple-stm32-STM32_NR_INTERRUPTS: +.. doxygendefine:: STM32_NR_INTERRUPTS +.. doxygendefine:: STM32_SRAM_END + +Clock Speeds +------------ + +The macros in this section are related to clock rates. As such, they +are really part of the configuration of the MCU, rather than inherent +characteristics of the MCU itself. For instance, it's possible to +change the PCLK1 and PCLK2 clock rates by reconfiguring the :ref:`RCC +<libmaple-rcc>`. libmaple proper never changes any clock rates, but it +does have APIs for doing so (such as :ref:`rcc_configure_pll() +<libmaple-rcc-rcc_configure_pll>`). Because of this, be careful when +using the macros in this section, as they assume that some values are +constant which in fact may be changed. + +The values these macros actually take are typically the maximum values +supported by the MCU. Since these are their actual values in practice +(at least in LeafLabs' current use cases, which have the chips running +as fast as possible), they're still considered useful. + +.. doxygendefine:: STM32_PCLK1 +.. doxygendefine:: STM32_PCLK2 + +The following macro, ``STM32_DELAY_US_MULT``, is a libmaple +implementation detail. It was included in this public API page in a +previous release by mistake, and is not deprecated, but using it in +your own code is a bad idea. + +.. doxygendefine:: STM32_DELAY_US_MULT + +Deprecated Macros +----------------- + +.. warning:: The macros in this section are deprecated, and are + available for backwards compatibility only. Do not use + them in new code. + +.. doxygendefine:: PCLK1 +.. doxygendefine:: PCLK2 +.. doxygendefine:: NR_INTERRUPTS +.. doxygendefine:: NR_GPIO_PORTS +.. doxygendefine:: DELAY_US_MULT diff --git a/docs/source/libmaple/api/systick.rst b/docs/source/libmaple/api/systick.rst new file mode 100644 index 0000000..45b6d63 --- /dev/null +++ b/docs/source/libmaple/api/systick.rst @@ -0,0 +1,62 @@ +.. highlight:: c + +.. _libmaple-systick: + +``systick.h`` +============= + +System timer (SysTick) support. + +.. contents:: Contents + :local: + +Types +----- + +.. doxygenstruct:: systick_reg_map + +Devices +------- + +None. + +Functions +--------- + +.. doxygenfunction:: systick_init +.. _libmaple-systick-enable: +.. doxygenfunction:: systick_enable +.. _libmaple-systick-disable: +.. doxygenfunction:: systick_disable +.. doxygenfunction:: systick_uptime +.. doxygenfunction:: systick_get_count +.. doxygenfunction:: systick_check_underflow + +Register Map Base Pointers +-------------------------- + +.. doxygendefine:: SYSTICK_BASE + +Register Bit Definitions +------------------------ + +Control and status register +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. doxygendefine:: SYSTICK_CSR_COUNTFLAG +.. doxygendefine:: SYSTICK_CSR_CLKSOURCE +.. doxygendefine:: SYSTICK_CSR_CLKSOURCE_EXTERNAL +.. doxygendefine:: SYSTICK_CSR_CLKSOURCE_CORE +.. doxygendefine:: SYSTICK_CSR_TICKINT +.. doxygendefine:: SYSTICK_CSR_TICKINT_PEND +.. doxygendefine:: SYSTICK_CSR_TICKINT_NO_PEND +.. doxygendefine:: SYSTICK_CSR_ENABLE +.. doxygendefine:: SYSTICK_CSR_ENABLE_MULTISHOT +.. doxygendefine:: SYSTICK_CSR_ENABLE_DISABLED + +Calibration value register +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. doxygendefine:: SYSTICK_CVR_NOREF +.. doxygendefine:: SYSTICK_CVR_SKEW +.. doxygendefine:: SYSTICK_CVR_TENMS diff --git a/docs/source/libmaple/api/timer.rst b/docs/source/libmaple/api/timer.rst new file mode 100644 index 0000000..f315cb0 --- /dev/null +++ b/docs/source/libmaple/api/timer.rst @@ -0,0 +1,453 @@ +.. highlight:: c +.. _libmaple-timer: + +``timer.h`` +=========== + +Timer support. + +.. contents:: Contents + :local: + +Types +----- + +The timer register map type, unlike that for most other peripherals in +libmaple, is a union rather than a struct. This is due to the fact +that there are advanced, general purpose, and basic timers. Thus, +each kind of timer has a register map type, and a ``union +timer_reg_map`` ties it all together. + +.. doxygenstruct:: timer_adv_reg_map +.. doxygenstruct:: timer_gen_reg_map +.. doxygenstruct:: timer_bas_reg_map +.. doxygenunion:: timer_reg_map +.. doxygenenum:: timer_type +.. doxygenstruct:: timer_dev +.. doxygenenum:: timer_mode +.. doxygenenum:: timer_channel +.. doxygenenum:: timer_interrupt_id +.. doxygenenum:: timer_dma_base_addr +.. doxygenenum:: timer_oc_mode +.. doxygenenum:: timer_oc_mode_flags + +Devices +------- + +.. doxygenvariable:: TIMER1 +.. doxygenvariable:: TIMER2 +.. doxygenvariable:: TIMER3 +.. doxygenvariable:: TIMER4 +.. doxygenvariable:: TIMER5 +.. doxygenvariable:: TIMER6 +.. doxygenvariable:: TIMER7 +.. doxygenvariable:: TIMER8 + +Functions +--------- + +Enabling and Disabling +~~~~~~~~~~~~~~~~~~~~~~ + +.. doxygenfunction:: timer_init +.. doxygenfunction:: timer_init_all +.. doxygenfunction:: timer_disable +.. doxygenfunction:: timer_disable_all + +General Configuration +~~~~~~~~~~~~~~~~~~~~~ + +.. doxygenfunction:: timer_set_mode +.. doxygenfunction:: timer_foreach + +Count and Prescaler +~~~~~~~~~~~~~~~~~~~ + +.. doxygenfunction:: timer_get_count +.. doxygenfunction:: timer_set_count +.. doxygenfunction:: timer_pause +.. doxygenfunction:: timer_resume +.. doxygenfunction:: timer_generate_update +.. doxygenfunction:: timer_get_prescaler +.. doxygenfunction:: timer_set_prescaler +.. doxygenfunction:: timer_get_reload +.. doxygenfunction:: timer_set_reload + +Interrupts +~~~~~~~~~~ + +.. doxygenfunction:: timer_attach_interrupt +.. doxygenfunction:: timer_detach_interrupt +.. doxygenfunction:: timer_enable_irq +.. doxygenfunction:: timer_disable_irq + +Capture/Compare +~~~~~~~~~~~~~~~ + +.. doxygenfunction:: timer_get_compare +.. doxygenfunction:: timer_set_compare +.. doxygenfunction:: timer_cc_enable +.. doxygenfunction:: timer_cc_disable +.. doxygenfunction:: timer_cc_get_pol +.. doxygenfunction:: timer_cc_set_pol +.. doxygenfunction:: timer_oc_set_mode + +DMA +~~~ + +.. doxygenfunction:: timer_dma_enable_trg_req +.. doxygenfunction:: timer_dma_disable_trg_req +.. doxygenfunction:: timer_dma_enable_req +.. doxygenfunction:: timer_dma_get_burst_len +.. doxygenfunction:: timer_dma_set_burst_len +.. doxygenfunction:: timer_dma_get_base_addr +.. doxygenfunction:: timer_dma_set_base_addr + +Register Map Base Pointers +-------------------------- + +.. doxygendefine:: TIMER1_BASE +.. doxygendefine:: TIMER2_BASE +.. doxygendefine:: TIMER3_BASE +.. doxygendefine:: TIMER4_BASE +.. doxygendefine:: TIMER5_BASE +.. doxygendefine:: TIMER6_BASE +.. doxygendefine:: TIMER7_BASE +.. doxygendefine:: TIMER8_BASE + +Register Bit Definitions +------------------------ + +Control register 1 (CR1) +~~~~~~~~~~~~~~~~~~~~~~~~ + +.. doxygendefine:: TIMER_CR1_ARPE_BIT +.. doxygendefine:: TIMER_CR1_DIR_BIT +.. doxygendefine:: TIMER_CR1_OPM_BIT +.. doxygendefine:: TIMER_CR1_URS_BIT +.. doxygendefine:: TIMER_CR1_UDIS_BIT +.. doxygendefine:: TIMER_CR1_CEN_BIT + +.. doxygendefine:: TIMER_CR1_CKD +.. doxygendefine:: TIMER_CR1_CKD_1TCKINT +.. doxygendefine:: TIMER_CR1_CKD_2TCKINT +.. doxygendefine:: TIMER_CR1_CKD_4TICKINT +.. doxygendefine:: TIMER_CR1_ARPE +.. doxygendefine:: TIMER_CR1_CKD_CMS +.. doxygendefine:: TIMER_CR1_CKD_CMS_EDGE +.. doxygendefine:: TIMER_CR1_CKD_CMS_CENTER1 +.. doxygendefine:: TIMER_CR1_CKD_CMS_CENTER2 +.. doxygendefine:: TIMER_CR1_CKD_CMS_CENTER3 +.. doxygendefine:: TIMER_CR1_DIR +.. doxygendefine:: TIMER_CR1_OPM +.. doxygendefine:: TIMER_CR1_URS +.. doxygendefine:: TIMER_CR1_UDIS +.. doxygendefine:: TIMER_CR1_CEN + +Control register 2 (CR2) +~~~~~~~~~~~~~~~~~~~~~~~~ + +.. doxygendefine:: TIMER_CR2_OIS4_BIT +.. doxygendefine:: TIMER_CR2_OIS3N_BIT +.. doxygendefine:: TIMER_CR2_OIS3_BIT +.. doxygendefine:: TIMER_CR2_OIS2N_BIT +.. doxygendefine:: TIMER_CR2_OIS2_BIT +.. doxygendefine:: TIMER_CR2_OIS1N_BIT +.. doxygendefine:: TIMER_CR2_OIS1_BIT +.. doxygendefine:: TIMER_CR2_TI1S_BIT +.. doxygendefine:: TIMER_CR2_CCDS_BIT +.. doxygendefine:: TIMER_CR2_CCUS_BIT +.. doxygendefine:: TIMER_CR2_CCPC_BIT + +.. doxygendefine:: TIMER_CR2_OIS4 +.. doxygendefine:: TIMER_CR2_OIS3N +.. doxygendefine:: TIMER_CR2_OIS3 +.. doxygendefine:: TIMER_CR2_OIS2N +.. doxygendefine:: TIMER_CR2_OIS2 +.. doxygendefine:: TIMER_CR2_OIS1N +.. doxygendefine:: TIMER_CR2_OIS1 +.. doxygendefine:: TIMER_CR2_TI1S +.. doxygendefine:: TIMER_CR2_MMS +.. doxygendefine:: TIMER_CR2_MMS_RESET +.. doxygendefine:: TIMER_CR2_MMS_ENABLE +.. doxygendefine:: TIMER_CR2_MMS_UPDATE +.. doxygendefine:: TIMER_CR2_MMS_COMPARE_PULSE +.. doxygendefine:: TIMER_CR2_MMS_COMPARE_OC1REF +.. doxygendefine:: TIMER_CR2_MMS_COMPARE_OC2REF +.. doxygendefine:: TIMER_CR2_MMS_COMPARE_OC3REF +.. doxygendefine:: TIMER_CR2_MMS_COMPARE_OC4REF +.. doxygendefine:: TIMER_CR2_CCDS +.. doxygendefine:: TIMER_CR2_CCUS +.. doxygendefine:: TIMER_CR2_CCPC + +Slave mode control register (SMCR) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. doxygendefine:: TIMER_SMCR_ETP_BIT +.. doxygendefine:: TIMER_SMCR_ECE_BIT +.. doxygendefine:: TIMER_SMCR_MSM_BIT + +.. doxygendefine:: TIMER_SMCR_ETP +.. doxygendefine:: TIMER_SMCR_ECE +.. doxygendefine:: TIMER_SMCR_ETPS +.. doxygendefine:: TIMER_SMCR_ETPS_OFF +.. doxygendefine:: TIMER_SMCR_ETPS_DIV2 +.. doxygendefine:: TIMER_SMCR_ETPS_DIV4 +.. doxygendefine:: TIMER_SMCR_ETPS_DIV8 +.. doxygendefine:: TIMER_SMCR_ETF +.. doxygendefine:: TIMER_SMCR_MSM +.. doxygendefine:: TIMER_SMCR_TS +.. doxygendefine:: TIMER_SMCR_TS_ITR0 +.. doxygendefine:: TIMER_SMCR_TS_ITR1 +.. doxygendefine:: TIMER_SMCR_TS_ITR2 +.. doxygendefine:: TIMER_SMCR_TS_ITR3 +.. doxygendefine:: TIMER_SMCR_TS_TI1F_ED +.. doxygendefine:: TIMER_SMCR_TS_TI1FP1 +.. doxygendefine:: TIMER_SMCR_TS_TI2FP2 +.. doxygendefine:: TIMER_SMCR_TS_ETRF +.. doxygendefine:: TIMER_SMCR_SMS +.. doxygendefine:: TIMER_SMCR_SMS_DISABLED +.. doxygendefine:: TIMER_SMCR_SMS_ENCODER1 +.. doxygendefine:: TIMER_SMCR_SMS_ENCODER2 +.. doxygendefine:: TIMER_SMCR_SMS_ENCODER3 +.. doxygendefine:: TIMER_SMCR_SMS_RESET +.. doxygendefine:: TIMER_SMCR_SMS_GATED +.. doxygendefine:: TIMER_SMCR_SMS_TRIGGER +.. doxygendefine:: TIMER_SMCR_SMS_EXTERNAL + +DMA/Interrupt enable register (DIER) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. doxygendefine:: TIMER_DIER_TDE_BIT +.. doxygendefine:: TIMER_DIER_CC4DE_BIT +.. doxygendefine:: TIMER_DIER_CC3DE_BIT +.. doxygendefine:: TIMER_DIER_CC2DE_BIT +.. doxygendefine:: TIMER_DIER_CC1DE_BIT +.. doxygendefine:: TIMER_DIER_UDE_BIT +.. doxygendefine:: TIMER_DIER_TIE_BIT +.. doxygendefine:: TIMER_DIER_CC4IE_BIT +.. doxygendefine:: TIMER_DIER_CC3IE_BIT +.. doxygendefine:: TIMER_DIER_CC2IE_BIT +.. doxygendefine:: TIMER_DIER_CC1IE_BIT +.. doxygendefine:: TIMER_DIER_UIE_BIT + +.. doxygendefine:: TIMER_DIER_TDE +.. doxygendefine:: TIMER_DIER_CC4DE +.. doxygendefine:: TIMER_DIER_CC3DE +.. doxygendefine:: TIMER_DIER_CC2DE +.. doxygendefine:: TIMER_DIER_CC1DE +.. doxygendefine:: TIMER_DIER_UDE +.. doxygendefine:: TIMER_DIER_TIE +.. doxygendefine:: TIMER_DIER_CC4IE +.. doxygendefine:: TIMER_DIER_CC3IE +.. doxygendefine:: TIMER_DIER_CC2IE +.. doxygendefine:: TIMER_DIER_CC1IE +.. doxygendefine:: TIMER_DIER_UIE + +Status register (SR) +~~~~~~~~~~~~~~~~~~~~ + +.. doxygendefine:: TIMER_SR_CC4OF_BIT +.. doxygendefine:: TIMER_SR_CC3OF_BIT +.. doxygendefine:: TIMER_SR_CC2OF_BIT +.. doxygendefine:: TIMER_SR_CC1OF_BIT +.. doxygendefine:: TIMER_SR_BIF_BIT +.. doxygendefine:: TIMER_SR_TIF_BIT +.. doxygendefine:: TIMER_SR_COMIF_BIT +.. doxygendefine:: TIMER_SR_CC4IF_BIT +.. doxygendefine:: TIMER_SR_CC3IF_BIT +.. doxygendefine:: TIMER_SR_CC2IF_BIT +.. doxygendefine:: TIMER_SR_CC1IF_BIT +.. doxygendefine:: TIMER_SR_UIF_BIT + +.. doxygendefine:: TIMER_SR_CC4OF +.. doxygendefine:: TIMER_SR_CC3OF +.. doxygendefine:: TIMER_SR_CC2OF +.. doxygendefine:: TIMER_SR_CC1OF +.. doxygendefine:: TIMER_SR_BIF +.. doxygendefine:: TIMER_SR_TIF +.. doxygendefine:: TIMER_SR_COMIF +.. doxygendefine:: TIMER_SR_CC4IF +.. doxygendefine:: TIMER_SR_CC3IF +.. doxygendefine:: TIMER_SR_CC2IF +.. doxygendefine:: TIMER_SR_CC1IF +.. doxygendefine:: TIMER_SR_UIF + +Event generation register (EGR) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. doxygendefine:: TIMER_EGR_TG_BIT +.. doxygendefine:: TIMER_EGR_CC4G_BIT +.. doxygendefine:: TIMER_EGR_CC3G_BIT +.. doxygendefine:: TIMER_EGR_CC2G_BIT +.. doxygendefine:: TIMER_EGR_CC1G_BIT +.. doxygendefine:: TIMER_EGR_UG_BIT + +.. doxygendefine:: TIMER_EGR_TG +.. doxygendefine:: TIMER_EGR_CC4G +.. doxygendefine:: TIMER_EGR_CC3G +.. doxygendefine:: TIMER_EGR_CC2G +.. doxygendefine:: TIMER_EGR_CC1G +.. doxygendefine:: TIMER_EGR_UG + +Capture/compare mode registers, common values +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. doxygendefine:: TIMER_CCMR_CCS_OUTPUT +.. doxygendefine:: TIMER_CCMR_CCS_INPUT_TI1 +.. doxygendefine:: TIMER_CCMR_CCS_INPUT_TI2 +.. doxygendefine:: TIMER_CCMR_CCS_INPUT_TRC + +Capture/compare mode register 1 (CCMR1) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. doxygendefine:: TIMER_CCMR1_OC2CE_BIT +.. doxygendefine:: TIMER_CCMR1_OC2PE_BIT +.. doxygendefine:: TIMER_CCMR1_OC2FE_BIT +.. doxygendefine:: TIMER_CCMR1_OC1CE_BIT +.. doxygendefine:: TIMER_CCMR1_OC1PE_BIT +.. doxygendefine:: TIMER_CCMR1_OC1FE_BIT + +.. doxygendefine:: TIMER_CCMR1_OC2CE +.. doxygendefine:: TIMER_CCMR1_OC2M +.. doxygendefine:: TIMER_CCMR1_IC2F +.. doxygendefine:: TIMER_CCMR1_OC2PE +.. doxygendefine:: TIMER_CCMR1_OC2FE +.. doxygendefine:: TIMER_CCMR1_IC2PSC +.. doxygendefine:: TIMER_CCMR1_CC2S +.. doxygendefine:: TIMER_CCMR1_CC2S_OUTPUT +.. doxygendefine:: TIMER_CCMR1_CC2S_INPUT_TI1 +.. doxygendefine:: TIMER_CCMR1_CC2S_INPUT_TI2 +.. doxygendefine:: TIMER_CCMR1_CC2S_INPUT_TRC +.. doxygendefine:: TIMER_CCMR1_OC1CE +.. doxygendefine:: TIMER_CCMR1_OC1M +.. doxygendefine:: TIMER_CCMR1_IC1F +.. doxygendefine:: TIMER_CCMR1_OC1PE +.. doxygendefine:: TIMER_CCMR1_OC1FE +.. doxygendefine:: TIMER_CCMR1_IC1PSC +.. doxygendefine:: TIMER_CCMR1_CC1S +.. doxygendefine:: TIMER_CCMR1_CC1S_OUTPUT +.. doxygendefine:: TIMER_CCMR1_CC1S_INPUT_TI1 +.. doxygendefine:: TIMER_CCMR1_CC1S_INPUT_TI2 +.. doxygendefine:: TIMER_CCMR1_CC1S_INPUT_TRC + +Capture/compare mode register 2 (CCMR2) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. doxygendefine:: TIMER_CCMR2_OC4CE_BIT +.. doxygendefine:: TIMER_CCMR2_OC4PE_BIT +.. doxygendefine:: TIMER_CCMR2_OC4FE_BIT +.. doxygendefine:: TIMER_CCMR2_OC3CE_BIT +.. doxygendefine:: TIMER_CCMR2_OC3PE_BIT +.. doxygendefine:: TIMER_CCMR2_OC3FE_BIT + +.. doxygendefine:: TIMER_CCMR2_OC4CE +.. doxygendefine:: TIMER_CCMR2_OC4M +.. doxygendefine:: TIMER_CCMR2_IC2F +.. doxygendefine:: TIMER_CCMR2_OC4PE +.. doxygendefine:: TIMER_CCMR2_OC4FE +.. doxygendefine:: TIMER_CCMR2_IC2PSC +.. doxygendefine:: TIMER_CCMR2_CC4S +.. doxygendefine:: TIMER_CCMR1_CC4S_OUTPUT +.. doxygendefine:: TIMER_CCMR1_CC4S_INPUT_TI1 +.. doxygendefine:: TIMER_CCMR1_CC4S_INPUT_TI2 +.. doxygendefine:: TIMER_CCMR1_CC4S_INPUT_TRC +.. doxygendefine:: TIMER_CCMR2_OC3CE +.. doxygendefine:: TIMER_CCMR2_OC3M +.. doxygendefine:: TIMER_CCMR2_IC1F +.. doxygendefine:: TIMER_CCMR2_OC3PE +.. doxygendefine:: TIMER_CCMR2_OC3FE +.. doxygendefine:: TIMER_CCMR2_IC1PSC +.. doxygendefine:: TIMER_CCMR2_CC3S +.. doxygendefine:: TIMER_CCMR1_CC3S_OUTPUT +.. doxygendefine:: TIMER_CCMR1_CC3S_INPUT_TI1 +.. doxygendefine:: TIMER_CCMR1_CC3S_INPUT_TI2 +.. doxygendefine:: TIMER_CCMR1_CC3S_INPUT_TRC + +Capture/compare enable register (CCER) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. doxygendefine:: TIMER_CCER_CC4P_BIT +.. doxygendefine:: TIMER_CCER_CC4E_BIT +.. doxygendefine:: TIMER_CCER_CC3P_BIT +.. doxygendefine:: TIMER_CCER_CC3E_BIT +.. doxygendefine:: TIMER_CCER_CC2P_BIT +.. doxygendefine:: TIMER_CCER_CC2E_BIT +.. doxygendefine:: TIMER_CCER_CC1P_BIT +.. doxygendefine:: TIMER_CCER_CC1E_BIT + +.. doxygendefine:: TIMER_CCER_CC4P +.. doxygendefine:: TIMER_CCER_CC4E +.. doxygendefine:: TIMER_CCER_CC3P +.. doxygendefine:: TIMER_CCER_CC3E +.. doxygendefine:: TIMER_CCER_CC2P +.. doxygendefine:: TIMER_CCER_CC2E +.. doxygendefine:: TIMER_CCER_CC1P +.. doxygendefine:: TIMER_CCER_CC1E + +Break and dead-time register (BDTR) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. doxygendefine:: TIMER_BDTR_MOE_BIT +.. doxygendefine:: TIMER_BDTR_AOE_BIT +.. doxygendefine:: TIMER_BDTR_BKP_BIT +.. doxygendefine:: TIMER_BDTR_BKE_BIT +.. doxygendefine:: TIMER_BDTR_OSSR_BIT +.. doxygendefine:: TIMER_BDTR_OSSI_BIT + +.. doxygendefine:: TIMER_BDTR_MOE +.. doxygendefine:: TIMER_BDTR_AOE +.. doxygendefine:: TIMER_BDTR_BKP +.. doxygendefine:: TIMER_BDTR_BKE +.. doxygendefine:: TIMER_BDTR_OSSR +.. doxygendefine:: TIMER_BDTR_OSSI +.. doxygendefine:: TIMER_BDTR_LOCK +.. doxygendefine:: TIMER_BDTR_LOCK_OFF +.. doxygendefine:: TIMER_BDTR_LOCK_LEVEL1 +.. doxygendefine:: TIMER_BDTR_LOCK_LEVEL2 +.. doxygendefine:: TIMER_BDTR_LOCK_LEVEL3 +.. doxygendefine:: TIMER_BDTR_DTG + +DMA control register (DCR) +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. doxygendefine:: TIMER_DCR_DBL +.. doxygendefine:: TIMER_DCR_DBL_1BYTE +.. doxygendefine:: TIMER_DCR_DBL_2BYTE +.. doxygendefine:: TIMER_DCR_DBL_3BYTE +.. doxygendefine:: TIMER_DCR_DBL_4BYTE +.. doxygendefine:: TIMER_DCR_DBL_5BYTE +.. doxygendefine:: TIMER_DCR_DBL_6BYTE +.. doxygendefine:: TIMER_DCR_DBL_7BYTE +.. doxygendefine:: TIMER_DCR_DBL_8BYTE +.. doxygendefine:: TIMER_DCR_DBL_9BYTE +.. doxygendefine:: TIMER_DCR_DBL_10BYTE +.. doxygendefine:: TIMER_DCR_DBL_11BYTE +.. doxygendefine:: TIMER_DCR_DBL_12BYTE +.. doxygendefine:: TIMER_DCR_DBL_13BYTE +.. doxygendefine:: TIMER_DCR_DBL_14BYTE +.. doxygendefine:: TIMER_DCR_DBL_15BYTE +.. doxygendefine:: TIMER_DCR_DBL_16BYTE +.. doxygendefine:: TIMER_DCR_DBL_17BYTE +.. doxygendefine:: TIMER_DCR_DBL_18BYTE +.. doxygendefine:: TIMER_DCR_DBA +.. doxygendefine:: TIMER_DCR_DBA_CR1 +.. doxygendefine:: TIMER_DCR_DBA_CR2 +.. doxygendefine:: TIMER_DCR_DBA_SMCR +.. doxygendefine:: TIMER_DCR_DBA_DIER +.. doxygendefine:: TIMER_DCR_DBA_SR +.. doxygendefine:: TIMER_DCR_DBA_EGR +.. doxygendefine:: TIMER_DCR_DBA_CCMR1 +.. doxygendefine:: TIMER_DCR_DBA_CCMR2 +.. doxygendefine:: TIMER_DCR_DBA_CCER +.. doxygendefine:: TIMER_DCR_DBA_CNT +.. doxygendefine:: TIMER_DCR_DBA_PSC +.. doxygendefine:: TIMER_DCR_DBA_ARR +.. doxygendefine:: TIMER_DCR_DBA_RCR +.. doxygendefine:: TIMER_DCR_DBA_CCR1 +.. doxygendefine:: TIMER_DCR_DBA_CCR2 +.. doxygendefine:: TIMER_DCR_DBA_CCR3 +.. doxygendefine:: TIMER_DCR_DBA_CCR4 +.. doxygendefine:: TIMER_DCR_DBA_BDTR +.. doxygendefine:: TIMER_DCR_DBA_DCR +.. doxygendefine:: TIMER_DCR_DBA_DMAR diff --git a/docs/source/libmaple/api/usart.rst b/docs/source/libmaple/api/usart.rst new file mode 100644 index 0000000..68f2c37 --- /dev/null +++ b/docs/source/libmaple/api/usart.rst @@ -0,0 +1,197 @@ +.. highlight:: c +.. _libmaple-usart: + +``usart.h`` +=========== + +Universal Synchronous/Asynchronous Receiver/Transmitter (USART, or +commonly *serial port*) support. + +.. contents:: Contents + :local: + +Types +----- + +.. doxygenstruct:: usart_reg_map +.. doxygenstruct:: usart_dev + +Devices +------- + +.. doxygenvariable:: USART1 +.. doxygenvariable:: USART2 +.. doxygenvariable:: USART3 +.. doxygenvariable:: UART4 +.. doxygenvariable:: UART5 + +Functions +--------- + +.. doxygenfunction:: usart_init +.. doxygenfunction:: usart_set_baud_rate +.. doxygenfunction:: usart_enable +.. doxygenfunction:: usart_disable +.. doxygenfunction:: usart_disable_all +.. doxygenfunction:: usart_foreach +.. doxygenfunction:: usart_rx +.. doxygenfunction:: usart_tx +.. doxygenfunction:: usart_putudec +.. doxygenfunction:: usart_putc +.. doxygenfunction:: usart_putstr +.. doxygenfunction:: usart_getc +.. doxygenfunction:: usart_data_available +.. doxygenfunction:: usart_reset_rx + +Register Map Base Pointers +-------------------------- + +.. doxygendefine:: USART1_BASE +.. doxygendefine:: USART2_BASE +.. doxygendefine:: USART3_BASE +.. doxygendefine:: UART4_BASE +.. doxygendefine:: UART5_BASE + +Register Bit Definitions +------------------------ + +Status Register +~~~~~~~~~~~~~~~ + +.. doxygendefine:: USART_SR_CTS_BIT +.. doxygendefine:: USART_SR_LBD_BIT +.. doxygendefine:: USART_SR_TXE_BIT +.. doxygendefine:: USART_SR_TC_BIT +.. doxygendefine:: USART_SR_RXNE_BIT +.. doxygendefine:: USART_SR_IDLE_BIT +.. doxygendefine:: USART_SR_ORE_BIT +.. doxygendefine:: USART_SR_NE_BIT +.. doxygendefine:: USART_SR_FE_BIT +.. doxygendefine:: USART_SR_PE_BIT + +.. doxygendefine:: USART_SR_CTS +.. doxygendefine:: USART_SR_LBD +.. doxygendefine:: USART_SR_TXE +.. doxygendefine:: USART_SR_TC +.. doxygendefine:: USART_SR_RXNE +.. doxygendefine:: USART_SR_IDLE +.. doxygendefine:: USART_SR_ORE +.. doxygendefine:: USART_SR_NE +.. doxygendefine:: USART_SR_FE +.. doxygendefine:: USART_SR_PE + +Data register +~~~~~~~~~~~~~ + +.. doxygendefine:: USART_DR_DR + +Baud Rate Register +~~~~~~~~~~~~~~~~~~ + +.. doxygendefine:: USART_BRR_DIV_MANTISSA +.. doxygendefine:: USART_BRR_DIV_FRACTION + +Control Register 1 +~~~~~~~~~~~~~~~~~~ + +.. doxygendefine:: USART_CR1_UE_BIT +.. doxygendefine:: USART_CR1_M_BIT +.. doxygendefine:: USART_CR1_WAKE_BIT +.. doxygendefine:: USART_CR1_PCE_BIT +.. doxygendefine:: USART_CR1_PS_BIT +.. doxygendefine:: USART_CR1_PEIE_BIT +.. doxygendefine:: USART_CR1_TXEIE_BIT +.. doxygendefine:: USART_CR1_TCIE_BIT +.. doxygendefine:: USART_CR1_RXNEIE_BIT +.. doxygendefine:: USART_CR1_IDLEIE_BIT +.. doxygendefine:: USART_CR1_TE_BIT +.. doxygendefine:: USART_CR1_RE_BIT +.. doxygendefine:: USART_CR1_RWU_BIT +.. doxygendefine:: USART_CR1_SBK_BIT + +.. doxygendefine:: USART_CR1_UE +.. doxygendefine:: USART_CR1_M +.. doxygendefine:: USART_CR1_WAKE +.. doxygendefine:: USART_CR1_WAKE_IDLE +.. doxygendefine:: USART_CR1_WAKE_ADDR +.. doxygendefine:: USART_CR1_PCE +.. doxygendefine:: USART_CR1_PS +.. doxygendefine:: USART_CR1_PS_EVEN +.. doxygendefine:: USART_CR1_PS_ODD +.. doxygendefine:: USART_CR1_PEIE +.. doxygendefine:: USART_CR1_TXEIE +.. doxygendefine:: USART_CR1_TCIE +.. doxygendefine:: USART_CR1_RXNEIE +.. doxygendefine:: USART_CR1_IDLEIE +.. doxygendefine:: USART_CR1_TE +.. doxygendefine:: USART_CR1_RE +.. doxygendefine:: USART_CR1_RWU +.. doxygendefine:: USART_CR1_RWU_ACTIVE +.. doxygendefine:: USART_CR1_RWU_MUTE +.. doxygendefine:: USART_CR1_SBK + +Control Register 2 +~~~~~~~~~~~~~~~~~~ + +.. doxygendefine:: USART_CR2_LINEN_BIT +.. doxygendefine:: USART_CR2_CLKEN_BIT +.. doxygendefine:: USART_CR2_CPOL_BIT +.. doxygendefine:: USART_CR2_CPHA_BIT +.. doxygendefine:: USART_CR2_LBCL_BIT +.. doxygendefine:: USART_CR2_LBDIE_BIT +.. doxygendefine:: USART_CR2_LBDL_BIT + +.. doxygendefine:: USART_CR2_LINEN +.. doxygendefine:: USART_CR2_STOP +.. doxygendefine:: USART_CR2_STOP_BITS_1 +.. doxygendefine:: USART_CR2_STOP_BITS_POINT_5 +.. doxygendefine:: USART_CR2_STOP_BITS_1_POINT_5 +.. doxygendefine:: USART_CR2_STOP_BITS_2 +.. doxygendefine:: USART_CR2_CLKEN +.. doxygendefine:: USART_CR2_CPOL +.. doxygendefine:: USART_CR2_CPOL_LOW +.. doxygendefine:: USART_CR2_CPOL_HIGH +.. doxygendefine:: USART_CR2_CPHA +.. doxygendefine:: USART_CR2_CPHA_FIRST +.. doxygendefine:: USART_CR2_CPHA_SECOND +.. doxygendefine:: USART_CR2_LBCL +.. doxygendefine:: USART_CR2_LBDIE +.. doxygendefine:: USART_CR2_LBDL +.. doxygendefine:: USART_CR2_LBDL_10_BIT +.. doxygendefine:: USART_CR2_LBDL_11_BIT +.. doxygendefine:: USART_CR2_ADD + +Control Register 3 +~~~~~~~~~~~~~~~~~~ + +.. doxygendefine:: USART_CR3_CTSIE_BIT +.. doxygendefine:: USART_CR3_CTSE_BIT +.. doxygendefine:: USART_CR3_RTSE_BIT +.. doxygendefine:: USART_CR3_DMAT_BIT +.. doxygendefine:: USART_CR3_DMAR_BIT +.. doxygendefine:: USART_CR3_SCEN_BIT +.. doxygendefine:: USART_CR3_NACK_BIT +.. doxygendefine:: USART_CR3_HDSEL_BIT +.. doxygendefine:: USART_CR3_IRLP_BIT +.. doxygendefine:: USART_CR3_IREN_BIT +.. doxygendefine:: USART_CR3_EIE_BIT + +.. doxygendefine:: USART_CR3_CTSIE +.. doxygendefine:: USART_CR3_CTSE +.. doxygendefine:: USART_CR3_RTSE +.. doxygendefine:: USART_CR3_DMAT +.. doxygendefine:: USART_CR3_DMAR +.. doxygendefine:: USART_CR3_SCEN +.. doxygendefine:: USART_CR3_NACK +.. doxygendefine:: USART_CR3_HDSEL +.. doxygendefine:: USART_CR3_IRLP +.. doxygendefine:: USART_CR3_IRLP_NORMAL +.. doxygendefine:: USART_CR3_IRLP_LOW_POWER +.. doxygendefine:: USART_CR3_IREN +.. doxygendefine:: USART_CR3_EIE + +Guard Time and Prescaler Register +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. doxygendefine:: USART_GTPR_GT +.. doxygendefine:: USART_GTPR_PSC diff --git a/docs/source/libmaple/api/util.rst b/docs/source/libmaple/api/util.rst new file mode 100644 index 0000000..54377c0 --- /dev/null +++ b/docs/source/libmaple/api/util.rst @@ -0,0 +1,54 @@ +.. highlight:: c +.. _libmaple-util: + +``<libmaple/util.h>`` +===================== + +.. TODO [0.2.0?] clean this up. + +Miscellaneous utility macros and procedures. + +.. contents:: Contents + :local: + +Bit Manipulation +---------------- + +The following macros are useful for bit manipulation. + +.. doxygendefine:: BIT +.. doxygendefine:: BIT_MASK_SHIFT +.. doxygendefine:: GET_BITS +.. doxygendefine:: IS_POWER_OF_TWO + +Failure Routines +---------------- + +``throb()`` is called by various routines to throb a built-in +LED. **Usually, you shouldn't call it yourself**; use something like +``ASSERT(0)`` (or the libc ``abort()`` function) instead. + +.. doxygenfunction:: throb + +Asserts and Debug Levels +------------------------ + +The level of libmaple's assertion support is determined by +``DEBUG_LEVEL``, as follows: + +.. doxygendefine:: DEBUG_LEVEL + +The current assert macros are ``ASSERT()`` and ``ASSERT_FAULT()``. +``ASSERT()`` is checked when ``DEBUG_LEVEL >= DEBUG_ALL``. +``ASSERT_FAULT()`` is checked whenever ``DEBUG_LEVEL >= DEBUG_FAULT``. + +As explained above, an assert macro is checked when the current +``DEBUG_LEVEL`` is high enough. If the debug level is too low, the +macro expands into a no-op that gets compiled away. + +If an assertion fails, execution is halted at the point of the failed +assertion. When libmaple has been configured properly (Wirish +performs this configuration by default), the built-in LED throbs in a +smooth pattern to signal the failed assertion (using +:c:func:`throb()`), and the file and line where the assert failed are +transmitted to the user as detailed in :ref:`lang-assert`. diff --git a/docs/source/libmaple/apis.rst b/docs/source/libmaple/apis.rst new file mode 100644 index 0000000..31f4902 --- /dev/null +++ b/docs/source/libmaple/apis.rst @@ -0,0 +1,14 @@ +.. _libmaple-apis: + +``libmaple`` API Index +====================== + +This is the master index for libmaple proper's APIs. + +**Contents** + +.. toctree:: + :maxdepth: 1 + :glob: + + api/* diff --git a/docs/source/libmaple/coding-standard.rst b/docs/source/libmaple/coding-standard.rst new file mode 100644 index 0000000..9ed56cc --- /dev/null +++ b/docs/source/libmaple/coding-standard.rst @@ -0,0 +1,422 @@ +.. _libmaple-coding-standard: + +Coding Standard +=============== + +This page documents the coding standard for :ref:`libmaple`. It's +intended as a guide for how you should structure any code you would +like included into the LeafLabs releases of libmaple. + +LeafLabs team members are required to follow these when producing new +code. Community contributors to libmaple are strongly encouraged to +do so; following these rules will greatly increase the probability +that your patches will be folded in. + +In general, follow this guide unless there's a very good reason not +to. Laziness doesn't count as a good reason. Most, if not all, of +these decisions are entirely arbitrary, but it's important for +readability that we be consistent. (If you notice an inconsistency, +you should fix it). + +Note that the file ``.dir-locals.el`` in the libmaple root directory +already ensures that many of these standards are followed by default +in Emacs (but not on Windows, where it would need to be named +``_dir_locals.el``, and no way, man). There's also some elisp +scattered about this file which will provide you additional help. + +Configuration for other editors (vim, etc.) would be nice! + +.. contents:: Contents + :local: + +License +------- + +.. highlight:: scheme + +Put an MIT license at the beginning of the file (look at any of our +source files for an example). Copyright should go either to you or to +LeafLabs, LLC. + +Emacs: if you don't like seeing the license, you should use elide-head +(which will hide it for you). You can use the following:: + + (require 'elide-head) + (setq programming-mode-hooks '(c-mode-hook c++-mode-hook)) + (add-to-list 'elide-head-headers-to-hide + '("The MIT License" . "DEALINGS IN\n [*] THE SOFTWARE")) + (add-to-list 'elide-head-headers-to-hide + '("The MIT License" . "DEALINGS IN THE\n...SOFTWARE")) + (dolist (hook programming-mode-hooks) + (add-hook hook (lambda () (elide-head)))) + +Whitespace +---------- + +TextMate users may find `this bundle +<https://github.com/glennr/uber-glory-tmbundle>`_ useful for +automatically converting tabs to spaces and removing trailing +whitespace at save time. + +- 4 space indents (set in ``.dir-locals.el``). + +- Unix newlines. + +- No tab characters (set in ``.dir-locals.el``). + +- No trailing whitespace. For help getting this (and no tab + characters) done automatically in Emacs, you can use + `code-fascism.el <https://github.com/mbolivar/code-fascism>`_. + +- Files end in exactly one newline. The presence of a newline at EOF + is already done by ``c-require-final-newline`` in recent versions of + Emacs. + +- Exactly two newlines separate source paragraphs (you do separate + your code into paragraphs, don't you?). + +- The first line in a function is non-blank. + +.. highlight:: cpp + +- Exactly one space after ``if``, ``else``, ``for``, and ``while``, + before the following ``{`` or ``(``. One space before ``else``, + after the preceding ``}``. For example:: + + // This is good; we like this: + if (foo) { + while (quux) { + bar(); + } + } else { + baz(); + } + + // THIS IS BAD! DON'T DO THIS: + if(foo){ + while(quux){ + bar(); + } + }else{ + baz(); + } + +- Exactly one space in between binary arithmetic, logical, and + comparison operators and their operands. Examples:: + + // This is good: + int x = a + b * (c - d); + if (x != 0 && a > 7) { + SerialUSB.println(x); + } + + // THIS IS BAD! + int x = a+b*(c-d); + if (x!=0 && a>7) { + SerialUSB.println(x); + } + + // This is good: + uint32 adc_data = ADC1_BASE->DR; + SerialUSB.println(adc_data); + + // THIS IS BAD! + uint32 adc_data = ADC1_BASE -> DR; + SerialUSB . println(adc_data); + +- No space between a unary operator and its operand. Examples:: + + // Good: + x++; + + // BAD! + x ++; + + // Good: + y = -x; + + // BAD! + y = - x; + +- If you need to break up a long line: + + * Prefer to break up long expressions after a binary operator. Example:: + + // Good: + if (some_really_long_conditional_wow_this_really_goes_on_forever || + maybe_something_else_could_happen_too) { + ... + } + + // BAD! + if (some_really_long_conditional_wow_this_really_goes_on_forever + || maybe_something_else_could_happen_too) { + ... + } + + * When breaking up a function's arguments over multiple lines, align + the arguments on subsequent lines with the first argument. + Example:: + + // Good: + return_type value_i_got = function_with_a_really_long_name(argument1, + argument2, + argument3); + + // BAD! + return_type value_i_got = function_with_a_really_long_name(argument1, + argument2, + argument3); + + // BAD! + return_type value_i_got = function_with_a_really_long_name(argument1, + argument2, + argument3); + +- In function invocations, no space in between the function name and + the opening parenthesis. Example:: + + // Good: + SerialUSB.println("Hello, world!"); + + // BAD! + SerialUSB.println ("Hello, world!"); + +- Don't indent C code within a conditionally-compiled ``extern "C"`` + block. Example:: + + // Good: + #ifdef __cplusplus + extern "C"{ + #endif + + void some_c_function(void); + + #ifdef __cplusplus + } // extern "C" + #endif + + // BAD! + #ifdef __cplusplus + extern "C"{ + #endif + + void some_c_function(void); + + #ifdef __cplusplus + } // extern "C" + #endif + + Emacs does the "bad" behavior by default, which can be very + annoying. You can turn this off with :: + + (defun c-mode-inextern-lang-hook () + (setcdr (assq 'inextern-lang c-offsets-alist) '-)) + (add-hook 'c-mode-hook c-mode-inextern-lang-hook) + +Comments +-------- + +.. highlight:: c++ + +- Multi-line comments are pretty flexible. Any of these is fine:: + + /* Comment starts here. + * Continued lines have a '*' before them. + * The comment can end after the last line. + */ + + /* Comment starts here. + * The comment can end on the same line. */ + + /* + * You can also place a newline after the opening "/*". + */ + +- Doxygen comments are multi-line comments that begin with ``/**`` + instead. + +- Single-line comments are up to you. + +Braces +------ + +- Mostly `1TBS + <http://en.wikipedia.org/wiki/Indent_style#Variant:_1TBS>`_. The + only difference is that the opening brace of a function's definition + occurs exactly one space character after the closing parenthesis in + that function's parameter list. Example:: + + void func(void) { + ... + } + +Naming conventions +------------------ + +We'll handle the usual casing/underscore debate as follows. + +- First, ``Dont_Mix_Like_This``, because ``It_Looks_Really_Ugly``, ok? + [There's been some debate about this, and some exceptions are + already grandfathered in, so in order to settle it, let's call this + a "recommendation" instead of "requirement".] + +- Variables: Use underscores to separate words in C identifiers:: + + int some_example_name; + + User-facing C++ variables should be camel cased + (``thisIsAnExample``, ``boardPWMPins``, etc.), for consistency with + the Arduino style. It's probably a good idea for you to case + non-user facing C++ variables in the C style; this will help + disambiguate what's part of the Wirish API and what's not. + +- Classes: Pascal case. So ``ThisIsAClassName``, but ``thisIsNot``, + ``this_is_not``, and ``Dont_You_DareTryANYTHING_STUPID``. + +- Functions: C functions are all lowercase, and words are separated by + underscores. C++ method names are camel cased. + +- Structs: Usually like variables (``adc_dev``, ``adc_reg_map``, + etc.), but it's not crucial. Don't feel obliged to put ``_t`` at + the end of the type name; we don't. + +- Macros and constants: all caps, separated by underscores. C++ + variables with the ``const`` qualifier generally aren't considered + "constants" for the purposes of this rule; i.e., they are cased + according to the rules for variables. We make an exception for + ``PIN_MAP``, because it's the central Wirish data structure. + +- foo.h gets ``#ifdef``\ 'ed to ``_FOO_H_``. + +- Acronyms: The case of letters in an acronym is determined by the + case of the first letter in the acronym, which is determined by + following the above rules. Examples:: + + // Good: + void usb_func() { ... } + void frob_usb_disc() { ... } + class SomethingUSB { + void usbInit(); + void initUSB(); + }; + + // BAD: + class BadUsb { ... }; // say "GoodUSB" instead + void swizzle_USB_disc() { ... } // say "swizzle_usb_disc" instead + +Documentation +------------- + +- Doxygen comments on every user-facing function and type. + Additionally, individually document the fields and enumerator values + of nontrivial user-facing structs and enums. See any register map + type's definition for an example. + +- For libmaple proper, you don't need comments for each register bit + definition, since that's just repeating information better obtained + by reading ST RM0008. + +- Doxygen comments generally only belong on types, functions, + etc. that are part of the public user-facing API. + + This essentially means that if what you're writing is going to be + documented under http://leaflabs.com/docs/ (i.e., if there's `Sphinx + documentation <http://sphinx.pocoo.org/>`_ for it in the + `leaflabs-docs <https://github.com/leaflabs/leaflabs-docs>`_ + repository), then you need to write Doxygen comments. Further, + those Sphinx docs should use Breathe to pull the Doxygen out. (For + more information on this, see the `leaflabs-docs README + <https://raw.github.com/leaflabs/leaflabs-docs/master/README>`_). + + Because Breathe isn't totally mature yet, you won't always be able + to do this. In these cases, document the code "manually" using the + Sphinx `C and C++ domains + <http://sphinx.pocoo.org/domains.html#the-c-domain>`_. This should + be avoided if at all possible, since it creates a maintenance burden + of documenting things in two places at once, and makes it easier for + documentation to go stale. + + If you do have to document something manually, put a comment in the + source file informing future maintainers about it, so they'll pay + extra attention when making changes. + +- When adding peripheral support, it would be nice if you put + longer-form comments into the libmaple ``notes/`` directory, with a + comment in the corresponding .h file referring to it. See the + :ref:`dac.h <libmaple-dac>` source for an example. + + This lets us keep the source files relatively free of "introductory" + material, while allowing new readers a convenient starting point. + These longer-form notes also have a habit of turning into official, + user-facing documentation (or `wiki <http://wiki.leaflabs.com>`_ + pages). + +- **For libmaple proper**, the convention is to document any + user-facing function at the point where it is defined. In + particular, this means you should document an externally-linked + function defined in a .c file in that .c file, not in the header + file where it is declared to the user. + + **For Wirish**, the convention is to put the documentation in the + header file where the function is declared. + +General Formatting +------------------ + +.. highlight:: scheme + +- Keep it 80-column clean. + + Emacs users: this means that the largest column number is 79. You + should turn on column number mode to help you out:: + + (column-number-mode 1) + + You can get more help from `lineker-mode + <http://www.helsinki.fi/~sjpaavol/programs/lineker.el>`_. Just put + lineker.el somewhere in your load-path, and:: + + (require 'lineker) + (dolist (hook '(c-mode-hook c++-mode-hook)) + (add-hook hook (lambda () (lineker-mode 1)))) + +.. highlight:: cpp + +Language Features +----------------- + +In libmaple proper, aim for C99 compatibility. Some GCC extensions +are OK, but `don't get crazy <http://www.youtube.com/watch?v=jZkdcYlOn5M>`_. + +Explicitly approved GCC extensions: + + * `asm volatile <http://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html>`_ + + * `Nested functions <http://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html>`_ + +In Wirish, generally be very conservative when using C++ features that +aren't part of C. We are forced to use C++ for Arduino compatibility +(and the general Arduino style of conflating objects and libraries), +but it's an angry beast, and we don't want to provoke it. **The +mantra is "C with classes"**. + +Explicitly approved C++ features: + + * Initializers that aren't constant; e.g. the ``gpio_dev*`` values + in a ``PIN_MAP``. + + * Default arguments: e.g., the timeout argument in + :ref:`lang-waitforbuttonpress`. + +Explicitly forbidden C++ features: + + * Templates + +Conditionally allowed C++ features: + + * Operator overloading: Never allowed when it's just for style. + Probably fine when you're implementing a class that models a + mathematical structure, and you'd like to implement + e.g. ``operator+()``. + diff --git a/docs/source/libmaple/contributing.rst b/docs/source/libmaple/contributing.rst new file mode 100644 index 0000000..25c6c17 --- /dev/null +++ b/docs/source/libmaple/contributing.rst @@ -0,0 +1,176 @@ +.. _libmaple-contributing: + +Contributing to libmaple +======================== + +First of all, thanks! Community contributions are what makes open +source great. + +If your patch is minor (you've found a typo, you've added a new +function, etc.), feel free to just make a `forum post +<http://forums.leaflabs.com>`_ describing your changes. + +If your changes are larger (you wrote a new library, you added support +for a new peripheral, etc.), we'd prefer you submit a pull request on +GitHub or send us a nicely-formatted patch via email. + +.. contents:: Contents + :local: + +.. _libmaple-faq-patches-preparing: + +Preparing Your Patch +-------------------- + +Before submitting a patch, please make sure it complies with the +:ref:`coding standard <libmaple-coding-standard>`. Consistent style throughout +the source tree is an important implementation objective for us, and a +patch that doesn't comply with the coding standard we've set forth is +likely to be sent back until it follows the standard. + +We would prefer if you release each new file you submit under the `MIT +license <http://www.opensource.org/licenses/mit-license.php>`_. See +e.g. `bkp.h +<https://github.com/leaflabs/libmaple/blob/master/libmaple/bkp.h#L1>`_ +for an example, and the coding standard for more details. Code +released under the `Lesser GPL +<http://www.gnu.org/copyleft/lesser.html>`_ may be accepted for +Wirish, but will almost certainly be rejected for libmaple proper. We +will not accept patches released under the `GPL +<http://www.gnu.org/licenses/gpl.html>`_. + +**We're not against the GPL**! It just doesn't suit our purposes for +libmaple. If you're interested in a GPLed library for ST +microcontrollers, check out `libopenstm32 +<http://www.hermann-uwe.de/blog/libopenstm32-a-free-software-firmware-library-for-stm32-arm-cortex-m3-microcontrollers>`_. +Also note that :ref:`libraries <libraries>` released under the GPL are +fine, we just don't want any core libmaple or Wirish code to be GPLed. + +.. _libmaple-faq-patches-github: + +Submitting Via GitHub Pull Request (Preferred) +---------------------------------------------- + +The most convenient way for you to contribute patches is to submit a +pull request on `GitHub <https://github.com>`_. Github provides +excellent code review interfaces, which will make it easy for us at +LeafLabs to communicate with you (and each other) about your patch. +It also makes it easy for us to merge your patch into the libmaple +source tree when the time comes. + +The steps to submit a pull request are as follows: + +1. If you don't already have one, get a `GitHub account + <https://github.com/plans>`_ (free). + +2. Fork libmaple, then clone your fork to the computer you code on. + GitHub provides detailed instructions on `forking and cloning a + repository <http://help.github.com/fork-a-repo/>`_. + +3. Push your commits to your GitHub libmaple fork (see instructions + linked in Step 2 for a step-by-step walkthrough on how to do this). + + Please add a signed-off-by line to your commits which certify your + `developer certificate of origin + <http://elinux.org/Developer_Certificate_Of_Origin>`_ [#fcert]_. + For example, if your name is "John Smith", and your email address + is "jsmith@example.com", just include the following line at the + bottom of your commit messages: + + ``Signed-off-by: John Smith <jsmith@example.com>`` + + If you've configured Git to know your name and email, you can + instruct it to insert this line automatically by calling ``git + commit`` with the ``-s`` flag. + +4. `Submit a pull request <http://help.github.com/pull-requests/>`_ to + the LeafLabs version of libmaple. + +.. _libmaple-faq-patches-email: + +Submitting Via Email +-------------------- + +If you're unfamiliar with Git or would prefer not to use GitHub, you +can always send us a patch via email at info@leaflabs.com. We'd love +it if you used the `Linux kernel patch format +<http://linux.yyz.us/patch-format.html>`_, but please at least include +the following information in your email: + +1. How you generated your patch (arguments to ``diff``, etc.) + +2. What git branch/commit or libmaple version your patch applies to + +3. A one-line summary of your changes, along with any other details + you think we should know. + +4. A sign-off line certifying your `developer certificate of origin + <http://elinux.org/Developer_Certificate_Of_Origin>`_ [#fcert]_. + +.. _libmaple-git-resources: + +Git Resources +------------- + +If you'd like to learn more about Git, we recommend the following +resources: + +* `The Git Community Book <http://book.git-scm.com/index.html>`_: A + collaboratively edited book on Git. + +* `Pro Git <http://progit.org/book/>`_: despite its title, this is a + fairly beginner-friendly source of information. + +* `Git - Revision Control Perfected (Linux Journal) + <http://www.linuxjournal.com/content/git-revision-control-perfected>`_: + Despite a title that makes it sound like it was written by a + marketing department, this is a very good introductory article on + basic Git concepts, and a solid primer on Git's internals. + +- `GitPhraseBook (openembedded.org) + <http://www.openembedded.org/index.php/GitPhraseBook>`_: A + cookbook-style list of common Git problems and their solutions. + +* `Understanding Git Conceptually + <http://www.eecs.harvard.edu/~cduan/technical/git/>`_: a good, + introductory tutorial on Git's fundamental concepts. + +* `Git for Computer Scientists + <http://eagain.net/articles/git-for-computer-scientists/>`_: if + you're comfortable with directed acyclic graphs, this resource + explains Git's functionality in graph-theoretic terms. + +.. highlight:: text + +.. rubric:: Footnotes + +.. [#fcert] Including this line indicates that you certify the following:: + + Developer's Certificate of Origin 1.1 + + By making a contribution to this project, I certify that: + + (a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + + (b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + + (c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. + + (d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. + + This may seem arbitrary, but it helps ensure that libmaple + remains open source. diff --git a/docs/source/libmaple/overview.rst b/docs/source/libmaple/overview.rst new file mode 100644 index 0000000..006f1d8 --- /dev/null +++ b/docs/source/libmaple/overview.rst @@ -0,0 +1,516 @@ +.. highlight:: c + +.. _libmaple-overview: + +Overview +======== + +This page is a general overview of :ref:`libmaple proper +<libmaple-vs-wirish>`. It describes libmaple's design, and names +implementation patterns to look for when using it. General +familiarity with the :ref:`STM32 <stm32>` is assumed; beginners should +start with the high-level :ref:`Wirish interface <language>` instead. +Examples are given from libmaple's sources. + +.. contents:: Contents + :local: + +Design Goals +------------ + +The central goal for libmaple proper is to provide a pleasant, +portable, and consistent set of interfaces for dealing with the +various series of STM32 microcontrollers. + +Portability in particular can be a problem when programming for the +STM32. While the various STM32 series are largely pin-compatible with +one another, the peripheral register maps between series often change +drastically, even when the functionality provided by the peripheral +doesn't change very much. This means that code which accesses +registers directly often needs to change when porting a program to a +different series MCU. + +ST's solution to this problem thus far has been to `issue +<http://www.st.com/internet/com/SOFTWARE_RESOURCES/SW_COMPONENT/FIRMWARE/stm32l1_stdperiph_lib.zip>`_ +`separate +<http://www.st.com/internet/com/SOFTWARE_RESOURCES/SW_COMPONENT/FIRMWARE/stm32f10x_stdperiph_lib.zip>`_ +`firmware +<http://www.st.com/internet/com/SOFTWARE_RESOURCES/SW_COMPONENT/FIRMWARE/stm32f2xx_stdperiph_lib.zip>`_ +`libraries +<http://www.st.com/internet/com/SOFTWARE_RESOURCES/SW_COMPONENT/FIRMWARE/stm32f4_dsp_stdperiph_lib.zip>`_; +one for each STM32 series. Along with these, they have released a +`number +<http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/APPLICATION_NOTE/DM00024853.pdf>`_ +of `application +<http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/APPLICATION_NOTE/DM00033267.pdf>`_ +`notes +<http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/APPLICATION_NOTE/DM00032987.pdf>`_ +describing the compatibility issues and how to migrate between series +by switching firmware libraries. Often, the migration advice is +essentially "rewrite your code"; this occurs, for example, with any +code involving GPIO or DMA being migrated between STM32F1 and STM32F2. + +Needless to say, this can be very annoying. (Didn't we solve this +sort of problem years ago?) When you just want your robot to fly, +your `LEDs to blink <http://www.youtube.com/watch?v=J845L45zqfk>`_, or +your `FM synthesizer <https://github.com/Ixox/preen>`_ to, well, +`synthesize <http://xhosxe.free.fr/IxoxFMSynth.mp3>`_, you probably +couldn't care less about dealing with a new set of registers. + +We want to make it easier to write portable STM32 code. To enable +that, libmaple abstracts away many hardware details behind portable +interfaces. We also want to make it easy for you to get your hands +dirty when need or desire arises. To that end, libmaple makes as few +assumptions as possible, and does its best to get out of your way when +you want it to leave. + +.. _libmaple-overview-devices: + +Libmaple's Device Model +----------------------- + +The libmaple device model is simple and stupid. This is a feature. + +*Device types* are the central libmaple abstraction; they exist to +provide portable interfaces to common peripherals, but they still let +you do nonportable things easily if you want to. + +The rules for device types are: + +- Device types are structs representing peripherals. The name of the + device type for peripheral "foo" is ``struct foo_dev`` (so for + foo=ADC, it's ``struct adc_dev``. For foo=DMA, it's ``struct + dma_dev``; etc.). These are always ``typedef``\ ed to ``foo_dev``. + +- Each device type contains any information needed or used by libmaple + for operating on the peripheral the type represents. Device types + are defined alongside declarations for portable support routines in + the header ``<libmaple/foo.h>`` (examples: :ref:`libmaple-adc`, + :ref:`libmaple-dma`). + +- Direct :ref:`register access <libmaple-overview-regmaps>` is + possible via the ``regs`` field in each device type. (Given a + ``foo_dev *foo``, you can read and write the BAR register + ``FOO_BAR`` with ``foo->regs->BAR``.) + +- An :ref:`rcc_clk_id <libmaple-rcc-rcc_clk_id>` for the device is + available in the ``clk_id`` field; this is an opaque type that can + be used to uniquely identifies the peripheral. (Given ``foo_dev + *foo``, you can check which foo you have by looking at + ``foo->clk_id``.) + +- The backend for each supported STM32 series statically initializes + devices as appropriate, and ensures that the peripheral support + header includes declarations for pointers to these statically + allocated devices. + +- Peripheral support functions usually expect a pointer to a device as + their first argument. These functions' implementations may vary + with the particular microcontroller you're targeting, but their + semantics try to stay the same. To migrate to a different target, + you'll often be able to simply recompile your program (and libmaple) + for the new target. + +- When complete portability is not possible, libmaple tries to keep + the nonportable bits in data, rather than code. + +Example: ``adc_dev`` +~~~~~~~~~~~~~~~~~~~~ + +These rules are best explained by example. The device type for ADC +peripherals is ``struct adc_dev``. Its definition is provided by +``<libmaple/adc.h>``:: + + typedef struct adc_dev { + adc_reg_map *regs; + rcc_clk_id clk_id; + } adc_dev; + +An ``adc_dev`` contains a pointer to its register map in the ``regs`` +field. This ``regs`` field is available on all device types. Its value +is a :ref:`register map base pointer +<libmaple-overview-regmaps-base-pts>` (like ``ADC1_BASE``, etc.) for +the peripheral, as determined by the current target. For example, two +equivalent expressions for reading the ADC1 regular data register are +``ADC1_BASE->DR`` and ``ADC1->regs->DR`` (though the first one is +faster). Manipulating registers directly via ``->regs`` is thus +always possible, but can be nonportable, and should you choose to do +this, it's up to you to get it right. + +An ``adc_dev`` also contains an ``rcc_clk_id`` for the ADC peripheral +it represents in the ``clk_id`` field. The ``rcc_clk_id`` enum type +has an enumerator for each peripheral supported by your series. For +example, the ADC peripherals' ``rcc_clk_id`` enumerators are +``RCC_ADC1``, ``RCC_ADC2``, and ``RCC_ADC3``. In general, an +``rcc_clk_id`` is useful not only for managing the clock line to a +peripheral, but also as a unique identifier for that peripheral. + +(Device types can be more complicated than this; ``adc_dev`` was +chosen as a simple example of the minimum you can expect.) + +Rather than have you define your own ``adc_dev``\ s, libmaple defines +them for you as appropriate for your target STM32 series. For example, +on STM32F1, the file libmaple/stm32f1/adc.c contains the following:: + + static adc_dev adc1 = { + .regs = ADC1_BASE, + .clk_id = RCC_ADC1, + }; + /** ADC1 device. */ + const adc_dev *ADC1 = &adc1; + + static adc_dev adc2 = { + .regs = ADC2_BASE, + .clk_id = RCC_ADC2, + }; + /** ADC2 device. */ + const adc_dev *ADC2 = &adc2; + + #if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY) + static adc_dev adc3 = { + .regs = ADC3_BASE, + .clk_id = RCC_ADC3, + }; + /** ADC3 device. */ + const adc_dev *ADC3 = &adc3; + #endif + +Since all supported STM32F1 targets support ADC1 and ADC2, libmaple +predefines corresponding ``adc_dev`` instances for you. To save space, +it avoids defining an ``adc_dev`` for ADC3 unless you are targeting a +high- or XL-density STM32F1, as medium- and lower density MCUs don't +have ADC3. + +Note that the structs themselves are static and are exposed only via +pointers. These pointers are declared in a series-specific ADC +header, ``<series/adc.h>`` which is included by ``<libmaple/adc.h>`` +based on the MCU you're targeting. (**Never include <series/foo.h> +directly**. Instead, include ``<libmaple/foo.h>`` and let it take +care of that for you.) On STM32F1, the series ADC header contains the +following:: + + extern const struct adc_dev *ADC1; + extern const struct adc_dev *ADC2; + #if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY) + extern const struct adc_dev *ADC3; + #endif + +In general, you access the predefined devices via these pointers. As +illustrated by the ADC example, the variables for these pointers +follow the naming scheme used in ST's reference manuals -- the pointer +to ADC1's ``adc_dev`` is named ``ADC1``, and so on. + +The :ref:`API documentation <libmaple-apis>` for the peripherals +you're interested in will list the available devices on each target. + +Using Devices +~~~~~~~~~~~~~ + +Peripheral support routines usually expect pointers to their device +types as their first arguments. Here are some ADC examples:: + + uint16 adc_read(const adc_dev *dev, uint8 channel); + static inline void adc_enable(const adc_dev *dev); + static inline void adc_disable(const adc_dev *dev); + +So, to read channel 2 of ADC1, you could call ``adc_read(ADC1, 2)``. +To disable ADC2, call ``adc_disable(ADC2)``; etc. + +That's it; there's nothing complicated here. In general, just follow +links from the :ref:`libmaple-apis` page to the header for the +peripheral you're interested in. It will explain the supported +functionality, both portable and series-specific. + +Segregating Non-portable Functionality into Data +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +As mentioned previously, when total portability isn't possible, +libmaple tries to do the right thing and segregate the nonportable +portions into data rather than code. The function +``adc_set_sample_rate()`` is a good example of how this works, and why +it's useful:: + + void adc_set_sample_rate(const adc_dev *dev, adc_smp_rate smp_rate); + +For example, while both STM32F1 and STM32F2 support setting the ADC +sample time via the same register interface, the actual sample times +supported are different. For instance, on STM32F1, available sample +times include 1.5, 7.5, and 13.5 ADC cycles. On STM32F2, none of these +are available, but 3, 15, and 28 ADC cycles are supported (which is +not true for STM32F1). To work with this, libmaple provides a single +function, ``adc_set_sample_rate()``, for setting an ADC controller's +channel sampling time, but the actual sample rates it takes are given +by the ``adc_smp_rate`` type, which is different on STM32F1 and +STM32F2. + +This is the STM32F1 implementation of adc_smp_rate:: + + typedef enum adc_smp_rate { + ADC_SMPR_1_5, /**< 1.5 ADC cycles */ + ADC_SMPR_7_5, /**< 7.5 ADC cycles */ + ADC_SMPR_13_5, /**< 13.5 ADC cycles */ + ADC_SMPR_28_5, /**< 28.5 ADC cycles */ + ADC_SMPR_41_5, /**< 41.5 ADC cycles */ + ADC_SMPR_55_5, /**< 55.5 ADC cycles */ + ADC_SMPR_71_5, /**< 71.5 ADC cycles */ + ADC_SMPR_239_5, /**< 239.5 ADC cycles */ + } adc_smp_rate; + +And here is the STM32F2 implementation:: + + typedef enum adc_smp_rate { + ADC_SMPR_3, /**< 3 ADC cycles */ + ADC_SMPR_15, /**< 15 ADC cycles */ + ADC_SMPR_28, /**< 28 ADC cycles */ + ADC_SMPR_56, /**< 56 ADC cycles */ + ADC_SMPR_84, /**< 84 ADC cycles */ + ADC_SMPR_112, /**< 112 ADC cycles */ + ADC_SMPR_144, /**< 144 ADC cycles */ + ADC_SMPR_480, /**< 480 ADC cycles */ + } adc_smp_rate; + +So, on F1, you could call ``adc_set_sample_rate(ADC1, ADC_SMPR_1_5)``, +and on F2, you could call ``adc_set_sample_rate(ADC1, +ADC_SMPR_3)``. If you're only interested in one of those series, then +that's all you need to know. + +However, if you're targeting multiple series, then this is useful +because it lets you put the actual sample time for the MCU you're +targeting into a variable (or macro, etc.), whose value depends on the +target you're compiling for. This lets you have a single codebase to +test and maintain, and lets you add support for a new target by simply +adding some new data. + +To continue the example, one easy way is to pick an ``adc_smp_rate`` +for each of STM32F1 and STM32F2 is with conditional compilation. Using +the :ref:`STM32_MCU_SERIES <libmaple-stm32-STM32_MCU_SERIES>` define +from :ref:`libmaple-stm32`, you can write:: + + #include <libmaple/adc.h> + #include <libmaple/stm32.h> + + #if STM32_MCU_SERIES == STM32_SERIES_F1 + /* Target is an STM32F1 */ + adc_smp_rate smp_rate = ADC_SMPR_1_5; + #elif STM32_MCU_SERIES == STM32_SERIES_F2 + /* Target is an STM32F2 */ + adc_smp_rate smp_rate = ADC_SMPR_3; + #else + #error "Unsupported STM32 target; can't pick a sample rate" + #endif + + void setup(void) { + adc_set_smp_rate(ADC1, smp_rate); + } + +Adding support for e.g. STM32F4 would only require adding a new +``#elif`` for that series. This is simple, but hackish, and can get +out of control if you're not careful. + +Another way to get the job done is to declare an ``extern adc_smp_rate +smp_rate``, and use the build system to compile a file defining +``smp_rate`` depending on your target. As was discussed earlier, this +is what libmaple does when choosing which files to use for defining +the appropriate ``adc_dev``\ s for your target. How to do this is +outside the scope of this overview, however. + +.. _libmaple-overview-regmaps: + +Register Maps +------------- + +Though we aim to enable libmaple's users to interact with the more +portable :ref:`device interface <libmaple-overview-devices>` as much +as possible, there will always be a need for efficient direct register +access. To allow for that, libmaple provides *register maps* as a +consistent set of names and abstractions for dealing with peripheral +registers and their bits. + +A *register map type* is a struct which names and provides access to a +peripheral's registers (we can use a struct because registers are +usually mapped into contiguous regions of memory). Here's an example +register map for the DAC peripheral on STM32F1 series MCUs (``__io`` +is just libmaple's way of saying ``volatile`` when referring to +register values):: + + typedef struct dac_reg_map { + __io uint32 CR; /**< Control register */ + __io uint32 SWTRIGR; /**< Software trigger register */ + __io uint32 DHR12R1; /**< Channel 1 12-bit right-aligned data + holding register */ + __io uint32 DHR12L1; /**< Channel 1 12-bit left-aligned data + holding register */ + __io uint32 DHR8R1; /**< Channel 1 8-bit left-aligned data + holding register */ + __io uint32 DHR12R2; /**< Channel 2 12-bit right-aligned data + holding register */ + __io uint32 DHR12L2; /**< Channel 2 12-bit left-aligned data + holding register */ + __io uint32 DHR8R2; /**< Channel 2 8-bit left-aligned data + holding register */ + __io uint32 DHR12RD; /**< Dual DAC 12-bit right-aligned data + holding register */ + __io uint32 DHR12LD; /**< Dual DAC 12-bit left-aligned data + holding register */ + __io uint32 DHR8RD; /**< Dual DAC 8-bit right-aligned data holding + register */ + __io uint32 DOR1; /**< Channel 1 data output register */ + __io uint32 DOR2; /**< Channel 2 data output register */ + } dac_reg_map; + +There are two things to notice here. First, if the chip reference +manual (for STM32F1, that's RM0008) names a register ``DAC_FOO``, then +``dac_reg_map`` has a field named ``FOO``. So, the Channel 1 12-bit +right-aligned data register (DAC_DHR12R1) is the ``DHR12R1`` field in +a ``dac_reg_map``. Second, if the reference manual describes a +register as "Foo bar register", the documentation for the +corresponding field has the same description. This consistency makes +it easy to search for a particular register, and, if you see one used +in a source file, to feel sure about what's going on just based on its +name. + +.. _libmaple-overview-regmaps-base-pts: + +So let's say you've included ``<libmaple/foo.h>``, and you want to +mess with some particular register. You'll do this using *register map +base pointers*, which are pointers to ``struct foo_reg_map``. What's +the name of the base pointer you want? That depends on if there's +more than one foo or not. If there's only one foo, then libmaple +guarantees there will be a ``#define`` that looks like like this:: + + #define FOO_BASE ((struct foo_reg_map*)0xDEADBEEF) + +That is, you're guaranteed there will be a pointer to the (only) +``foo_reg_map`` you want, and it will be called +``FOO_BASE``. (``0xDEADBEEF`` is the register map's *base address*, or +the fixed location in memory where the register map begins). Here's +an example for STM32F1:: + + #define DAC_BASE ((struct dac_reg_map*)0x40007400) + +Here are some examples for how to read and write to registers using +register map base pointers. + +* In order to write 2048 to the channel 1 12-bit left-aligned data + holding register (DAC_DHR12L1), you would write:: + + DAC_BASE->DHR12L1 = 2048; + +* In order to read the DAC control register, you would write:: + + uint32 cr = DAC_BASE->CR; + +That covers the case where there's a single foo peripheral. If +there's more than one (say, if there are *n*), then +``<libmaple/foo.h>`` provides the following:: + + #define FOO1_BASE ((struct foo_reg_map*)0xDEADBEEF) + #define FOO2_BASE ((struct foo_reg_map*)0xF00DF00D) + ... + #define FOOn_BASE ((struct foo_reg_map*)0x1EAF1AB5) + +Here are some examples for the ADCs on STM32F1:: + + #define ADC1_BASE ((struct adc_reg_map*)0x40012400) + #define ADC2_BASE ((struct adc_reg_map*)0x40012800) + +In order to read from the ADC1's regular data register (where the +results of ADC conversion are stored), you would write:: + + uint32 converted_result = ADC1_BASE->DR; + +Register Bit Definitions +------------------------ + +In ``<libmaple/foo.h>``, there will also be a variety of ``#define``\ +s for dealing with interesting bits in the xxx registers, called +*register bit definitions*. In keeping with the ST reference manuals, +these are named according to the scheme ``FOO_REG_FIELD``, where +"``REG``" refers to the register, and "``FIELD``" refers to the bit or +bits in ``REG`` that are special. + +Again, this is probably best explained by example. On STM32F1, each +Direct Memory Access (DMA) controller's register map has a certain +number of channel configuration registers (DMA_CCRx). In each of +these channel configuration registers, bit 14 is called the +``MEM2MEM`` bit, and bits 13 and 12 are the priority level (``PL``) +bits. Here are the register bit definitions for those fields on +STM32F1:: + + #define DMA_CCR_MEM2MEM_BIT 14 + #define DMA_CCR_MEM2MEM (1U << DMA_CCR_MEM2MEM_BIT) + #define DMA_CCR_PL (0x3 << 12) + #define DMA_CCR_PL_LOW (0x0 << 12) + #define DMA_CCR_PL_MEDIUM (0x1 << 12) + #define DMA_CCR_PL_HIGH (0x2 << 12) + #define DMA_CCR_PL_VERY_HIGH (0x3 << 12) + +Thus, to check if the ``MEM2MEM`` bit is set in DMA controller 1's +channel configuration register 2 (DMA_CCR2), you can write:: + + if (DMA1_BASE->CCR2 & DMA_CCR_MEM2MEM) { + /* MEM2MEM is set */ + } + +Certain register values occupy multiple bits. For example, the +priority level (PL) of a DMA channel is determined by bits 13 and 12 +of the corresponding channel configuration register. As shown above, +libmaple provides several register bit definitions for masking out the +individual PL bits and determining their meaning. For example, to set +the priority level of a DMA transfer to "high priority", you can +do a read-modify-write sequence on the DMA_CCR_PL bits like so:: + + uint32 ccr = DMA1_BASE->CCR2; + ccr &= ~DMA_CCR_PL; + ccr |= DMA_CCR_PL_HIGH; + DMA1_BASE->CCR2 = ccr; + +Of course, before doing that, you should check to make sure there's +not already a device-level function for performing the same task! (In +this case, there is. It's called :c:func:`dma_set_priority()`; see +:ref:`libmaple-dma`.) For instance, **none of the above code is +portable** to STM32F4, which uses DMA streams instead of channels for +this purpose. + +Peripheral Support Routines +--------------------------- + +This section describes patterns to look for in peripheral support +routines. + +In general, each device needs to be initialized before it can be used. +libmaple provides this initialization routine for each peripheral +``foo``; its name is ``foo_init()``. These initialization routines +turn on the clock to a device, and restore its register values to +their default settings. Here are a few examples:: + + /* From <libmaple/dma.h> */ + void dma_init(dma_dev *dev); + + /* From <libmaple/gpio.h> */ + void gpio_init(gpio_dev *dev); + void gpio_init_all(void); + +Note that, sometimes, there will be an additional initialization +routine for all available peripherals of a certain kind. + +Many peripherals also need additional configuration before they can be +used. These functions are usually called something along the lines of +``foo_enable()``, and often take additional arguments which specify a +particular configuration for the peripheral. Some examples:: + + /* From <libmaple/usart.h> */ + void usart_enable(usart_dev *dev); + + /* From <libmaple/i2c.h> */ + void i2c_master_enable(i2c_dev *dev, uint32 flags); + +After you've initialized, and potentially enabled, your peripheral, it +is now time to begin using it. The :ref:`libmaple API pages +<libmaple-apis>` are your friends here. + +.. rubric:: Footnotes + +.. [#fgpio] As an exception, GPIO ports are given letters instead of + numbers (``GPIOA`` and ``GPIOB`` instead of ``GPIO1`` and + ``GPIO2``, etc.). diff --git a/docs/source/libraries.rst b/docs/source/libraries.rst new file mode 100644 index 0000000..1ae0e87 --- /dev/null +++ b/docs/source/libraries.rst @@ -0,0 +1,80 @@ +.. highlight:: c++ +.. default-domain:: cpp + +.. _libraries: + +========================= + Maple Library Reference +========================= + +.. Note: if you port an Arduino library and document it here, be sure +.. to update compatibility.rst to reflect that fact. + +This page lists the extra libraries that are part of the :ref:`Maple +IDE <ide>` (along with the rest of :ref:`libmaple <libmaple>`). You +can use a library from within a sketch by going to Sketch > Import +Library... from within the IDE, then choosing the library you want. + +Any incompatibilities between the Maple and Arduino versions of a +library are noted in the library's documentation. + +.. contents:: Contents + :local: + +.. toctree:: + :hidden: + + libs/servo.rst + libs/wire.rst + +.. admonition:: **Looking for Something Else?** + + - See the :ref:`language` for information on the core functions + used for programming a Maple board. + + - If you're looking for something from the C standard library (like + ``atoi()``, for instance): the :ref:`CodeSourcery GCC compiler + <arm-gcc>` used to compile your programs is configured to link + against `newlib <http://sourceware.org/newlib/>`_, and allows the + use of any of its header files. However, dynamic memory allocation + (``malloc()``, etc.) is not available. + + - If you're looking for low-level hardware support libraries, see + the :ref:`libmaple Reference <libmaple>`. + +.. _libraries-servo: + +Servo +----- + +The :ref:`Servo <libs-servo>` library is provided for convenient +control of RC servomotors. + +.. _libraries-liquid-crystal: + +LiquidCrystal +------------- + +.. TODO [0.1.0] LiquidCrystal docs under libs/liquidcrystal.rst + +The LiquidCrystal library allows Maple to control LCD screens. For +more information, see the `Arduino LiquidCrystal documentation +<http://www.arduino.cc/en/Reference/LiquidCrystal>`_. + +**Arduino Compatibility** + +At this time, no incompatibilities between the Maple and Arduino +versions are known (although the Maple version should perform +significantly faster). Any observed differences should be considered +bugs, and reported on the forums. + +.. _libraries-wire: + +Wire +---- + +.. FIXME [0.0.13] Update with crenn's info + +We currently provide a soft (bit-banged) implementation of the +:ref:`Wire <libs-wire>` I2C library. A hardware version is planned +for Maple IDE release 0.1.0. diff --git a/docs/source/libs/servo.rst b/docs/source/libs/servo.rst new file mode 100644 index 0000000..80288c6 --- /dev/null +++ b/docs/source/libs/servo.rst @@ -0,0 +1,92 @@ +.. highlight:: cpp + +.. _libs-servo: + +Servo +===== + +This documents the Servo library for controlling RC servomotors. It +is implemented as a thin layer over the built-in :ref:`timer +peripherals <timers>`. + +You can use this library in the :ref:`IDE <ide>` by choosing the Servo +item under the Sketch > Import Library... menu. + +If you are using the :ref:`Unix toolchain <unix-toolchain>`, the +library is located in the ``/libraries/Servo/`` :ref:`libmaple` +directory. + +.. contents:: Contents + :local: + +Servo Class Reference +--------------------- + +You can construct a Servo object by including the declaration :: + + Servo servo; + +in your sketch. This will create a Servo object called ``servo``. +You can then use any of its methods; for instance, to control a +servomotor attached to pin 9, you could write :: + + servo.attach(9); + +.. doxygenclass:: Servo + :members: + +Arduino Compatibility +--------------------- + +The Servo class provides a public interface identical to the Arduino +version's documented functionality (as of Arduino 0021), so in most +cases, this library will be a drop-in replacement. + +However, there are some differences, essentially at the level of +implementation details. + +The major difference is that while the Arduino implementation drives +servos with "bit-banged" PWM (in the sense that timer interrupt +handlers are used to manually toggle pins), the Maple implementation +uses :ref:`timers <timers>` to drive the PWM directly. + +Consequently, **the Maple implementation only allows Servo instances +to attach to pins that support PWM**. + +To determine if a pin supports PWM, you can either check if "PWM" +appears next to its number on your board's silkscreen, or look for it +in the list of :ref:`boardPWMPins <lang-board-values-pwm-pins>` in +your board's :ref:`hardware documentation <index-boards>`. + +RC Servos expect a pulse approximately every 20ms. In the Maple +implementation, :ref:`periods <lang-hardwaretimer-setperiod>` are set +for entire timers, rather than individual channels. Thus, +``attach()``\ ing a Servo to a pin can interfere with other pins +associated with the same timer\ [#fard-servo]_. + +Because of this, we recommend connecting multiple servomotors to pins +which share a timer, in order to keep as many timers free for other +purposes as possible. Consult your board's :ref:`Timer Pin Map +<gpio-pin-maps>` to match up pins and timer channels. + +And here's some fine print: + +- Although it is not publicly documented to do so, the Arduino + implementation of `attach() + <http://arduino.cc/en/Reference/ServoAttach>`_ returns the timer + channel associated with the newly-attached pin, or 0 on failure (as + of Arduino 0021). The Maple implementation returns :ref:`true + <lang-constants-true>` on success, and :ref:`false + <lang-constants-false>` on failure (and this is its documented + behavior). + +- In another bit of undocumented behavior, the Arduino implementation + of write() also treats its argument as an angle or a pulse width + depending on its value. This is a bad idea, and we don't do it. + +.. rubric:: Footnotes + +.. [#fard-servo] The Arduino implementation also captures timer + channels in groups as more Servo objects are attached, but the + details of which channels have their periods reset when are + slightly different. diff --git a/docs/source/libs/wire.rst b/docs/source/libs/wire.rst new file mode 100644 index 0000000..2c5bed9 --- /dev/null +++ b/docs/source/libs/wire.rst @@ -0,0 +1,104 @@ +.. highlight:: cpp + +.. _libs-wire: + +Wire +==== + +.. TODO [0.1.0] Format this correctly, using Breathe + +This page documents the Wire library for the :ref:`i2c` protocol. You +can use this library in the :ref:`Maple IDE <ide>` by choosing the +Wire item under the Sketch > Import Library... menu. + +If you are using the :ref:`Unix toolchain <unix-toolchain>`, the +library is located in the ``/libraries/Wire/`` :ref:`libmaple` +directory. + +Wire Function Reference +----------------------- + +``Wire.begin()`` + Joins the i2c bus as master, using pin 20 as SDA and pin 21 as SCL + (this is compatible with the pin settings on the Arduino Mega). + +``Wire.begin(sda, scl)`` + Like ``Wire.begin()``, but with the given pins as SDA and + SCL. + +``Wire.beginTransmission(slave_address)`` + Set up a transmission to a slave device with the given (7-bit) + address. Bytes subsequently queued for transmission (using + ``Wire.send``) will be sent to ``slave_address`` when ``void + Wire.endTransmission()`` is called. + +``void Wire.send(byte)`` + Queues the given byte (``uint8`` or ``int``) to the slave address + previously specified by a call to ``Wire.beginTransmission``. At + most 32 bytes may be queued in a single transmission. + +``Wire.send(string)`` + Queues a given string (``char*``) for transmission. The characters + of the string are individually queued for transmission as + bytes. At most 32 bytes may be queued in a single transmission. + +``Wire.send(buffer, length)`` + Queues a byte buffer ``buffer`` (``uint8*`` or ``int*``), with + ``length`` elements, for transmission. At most 32 bytes may be + queued in a single transmission. + +``Wire.endTransmission()`` + Ends a transmission (begun by ``Wire.beginTransmission(uint8)``), + and actually sends the bytes queued by calls to Wire.send. + + The return value is one of the following status codes: + + * ``SUCCESS``: All bytes were transmitted successfully. + + * ``EDATA``: More than 32 bytes were queued for transmission. No + bytes are actually sent when this happens. + + * ``ENACKADDR``: Did not receive ACK on transmit of address. No + bytes are actually sent when this happens. + + * ``ENACKTRNS``: Did not receive ACK during transmit of data. Some + bytes may have been sent when this happens; however, the + transmission is aborted after the first byte of data which is + not ACKed by the slave device. + + * ``EOTHER``: Other error occurred. + +``Wire.requestFrom(address, num_bytes)`` + Requests ``num_bytes`` bytes from 7-bit slave address + address. Returns the actual number of bytes read. These bytes may + subsequently be read one at a time using ``Wire.receive()``. + + Note: if ``num_bytes`` exceeds the size of the transmit/receive + buffer (currently 32), it will be truncated to 32. + +``Wire.receive()`` + Get and return the next byte read during the previous call to + ``Wire.requestFrom(uint8, int)``. You can check how many bytes are + left to read using ``uint8 Wire.available()``. + +``Wire.available()`` + Returns the number of bytes which are still available for reading + (with ``Wire.receive()``) from the last call to + ``Wire.requestFrom(uint8, int)``. + +Arduino Compatibility +--------------------- + +.. FIXME [0.1.0] Replace this section when i2c Wire wrapper is done + +This implementation is synchronous, and thus supports only a subset of +the full Wire interface (however, the functionality which is supported +is fully compatible with Arduino). For now, please use the function +reference which follows when developing projects using our +implementation. + +Please note that the current implementation only supports master mode +using a bit-banged (software) protocol. For now, use of the hardware +:ref:`i2c` peripheral is only available through :ref:`libmaple-i2c`. + + diff --git a/docs/source/maple-ide-install.rst b/docs/source/maple-ide-install.rst new file mode 100644 index 0000000..7e9bfa2 --- /dev/null +++ b/docs/source/maple-ide-install.rst @@ -0,0 +1,176 @@ +.. highlight:: c++ + +.. _maple-ide-install: + +======================== + Maple IDE Installation +======================== + +If you still can't get the IDE installed after reading this page, +check the :ref:`troubleshooting page <troubleshooting>` for help with +some common problems. If all else fails, try our `forum`_, or `contact +us directly`_\ ! + +.. contents:: Contents + :local: + +Download +-------- + +.. FIXME [RELEASE] Update this for the release. + +This documentation was built from a development version of libmaple. +See the formally released `LeafLabs documentation +<http://leaflabs.com/docs/>`_ for more information about the current +Maple IDE release. + +.. Choose the correct version for your operating system: + +.. .. list-table:: +.. :widths: 15 30 +.. :header-rows: 1 + +.. * - Platform +.. - Status +.. - IDE Package +.. * - `Windows XP <http://static.leaflabs.com/pub/leaflabs/maple-ide/maple-ide-0.0.10-windowsxp32.zip>`_ +.. - Tested on Debian Wheezy (64-bit) and Mint 14.1 (64-bit) +.. * - `Linux <http://static.leaflabs.com/pub/leaflabs/maple-ide/maple-ide-0.0.10-linux32.tgz>`_ +.. - Tested on Ubuntu 10.04 (32-bit) +.. * - `Mac OS X <http://static.leaflabs.com/pub/leaflabs/maple-ide/maple-ide-0.0.10-macosx-10_6.dmg>`_ +.. - Tested on Snow Leopard (10.6) + +The package bundles together a compiler, an upload utility, a software +library, and a simple GUI text editor. All this software is `free and +open <http://www.fsf.org/>`_; we are grateful to the `Arduino +<http://arduino.cc/>`_, `CodeSourcery +<http://www.codesourcery.com/>`_, `GNU <http://www.gnu.org/>`_, and +`OpenMoko <http://openmoko.com/>`_ developers, as well as many others, +who allow us to reuse their software. + +**Looking for something older?** `Source archives and binaries +<http://static.leaflabs.com/pub/leaflabs/maple-ide/>`_ are available +for previously-released versions. + +Installation +------------ + +* :ref:`Windows <maple-ide-install-windows>` +* :ref:`Linux <maple-ide-install-linux>` +* :ref:`OS X <maple-ide-install-osx>` + +.. _maple-ide-install-windows: + +Windows XP (Legacy Only) +^^^^^^^^^^^^^^^^^^^^^^^^ + +.. note:: Note that while these instructions work on Windows XP, + changes in Windows 7 (and later) mean that you won't be able to install the + IDE without disabling driver signing on your computer. + `Users on the forum have reported a workaround + <http://forums.leaflabs.com/topic.php?id=73#post-788>`_, but we + only officially support the IDE on 32-bit Windows XP. + +First, extract all the files in the ZIP file to a suitable location on +your system (like your Desktop folder). Next, you have to install +some drivers. Sorry! + +.. _maple-ide-install-windows-drivers: + + +First, install DFU drivers (for uploading code to your Maple) using +the following steps. + +1. Plug your Maple into the USB port. + +2. Hit the reset button on your Maple (it's the small button at the + bottom left, labeled RESET). Notice that it blinks quickly 6 times, + then blinks slowly a few more times. + +3. Hit reset again, and this time push and hold the other button + during the 6 fast blinks (the button is on the top right; it is + labeled BUT). You can release it once the slow blinks start. + +4. Your Maple is now in :ref:`perpetual bootloader mode + <troubleshooting-perpetual-bootloader>`. This should give you a + chance to install the DFU drivers. + +5. Windows should now prompt you for some drivers. In the top level + directory of the Maple IDE, point Windows to + :file:`drivers/mapleDrv/dfu/`. + +Next, install serial drivers (for communicating with your Maple using +serial over USB). + +1. Reset your Maple and allow it to exit the bootloader (wait for the + slow blinking to stop). The Maple will next start running whatever + program was uploaded to it last. (New Maples will start running the + test program we upload to them before shipping them to you). + +2. Once Maple is running some user code, Windows should prompt you for + more drivers. Point windows to :file:`driver/mapleDrv/serial`. + +You can now run the Maple IDE by double-clicking on the +:command:`maple-ide` program from within the extracted IDE directory. + +.. _maple-ide-install-linux: + +Linux +^^^^^ + +.. _maple-ide-install-java: +.. note:: + + The IDE is written in Java and requires a compatible runtime (JRE). + + If you don't have one, they're usually pretty easy to install. + Oracle Java 1.6 and OpenJDK 1.6 are known to work, and runtimes + mostly compatible with Oracle Java 1.5+ should probably get the job + done. + + To install Java, try using your distribution's software packaging + tool and search for "JRE" or "java". On Debian-based systems + (including Ubuntu) you can try to install the OpenJDK 1.6 JRE + with:: + + $ sudo aptitude install openjdk-6-jre + +Extract the tarball to an appropriate location (like your home +directory or desktop). + +Make sure you have a Java runtime (JRE) installed; if you can run +:command:`java` from the shell, you should be fine. + +Next, run the script :file:`install-udev-rules.sh` in the extracted +IDE directory. It will ask for root permissions (you will be prompted +with something along the lines of ``[sudo] password for +<username>:``). You now need to restart udev:: + + $ sudo restart udev + +This will grant members of the group ``plugdev`` read/write access to +Maple devices over USB. Make sure that you are in that group by +running ``$ sudo adduser <your username> plugdev`` (which will ensure +access to the Maple, but may report that you are already a member of +that group). (For more information on why this is part of the install +process, see the :ref:`Unix toolchain quickstart <toolchain-udev>`). + +To run the Maple IDE, run :command:`maple-ide` from the shell, or +double-click on it if your window system supports it. + +Feel free to put the IDE directory wherever you want. As long as you +leave its internal structure unchanged, things should be fine. + +.. _maple-ide-install-osx: + +OS X +^^^^ + +Double-click on the :file:`.dmg` file you downloaded to mount the disk +image. From the mounted image, drag and drop the Maple IDE icon into +your computer's Applications folder. + +To run the Maple IDE, double-click the :command:`Maple IDE` +application you dragged into your computer's :file:`Applications` +folder. + diff --git a/docs/source/maple-quickstart.rst b/docs/source/maple-quickstart.rst new file mode 100644 index 0000000..a4bc55a --- /dev/null +++ b/docs/source/maple-quickstart.rst @@ -0,0 +1,210 @@ +.. highlight:: sh + +.. _maple-quickstart: + +======================== + Maple Quickstart Guide +======================== + +.. TODO [0.0.13]: Update the images; e.g., "to FLASH" is now "to Flash" +.. +.. Consider putting the images as a bundle somewhere under +.. static.leaflabs.com that gets downloaded and unpacked if they are +.. not present, but don't get crazy. + +You'll need a `Maple board <http://leaflabs.com/store/>`_, a `Mini-B +USB cable <http://www.google.com/products?q=mini-b+usb+cable>`_, a +functional computer, and possibly root (or "administrator") access to +that computer. + +If you have trouble along the way, try the :ref:`troubleshooting page +<troubleshooting>` for help with some common problems. If all else +fails, try our `forum`_, or `contact`_ us directly! + +.. contents:: Contents + :local: + +.. _maple-quickstart-get-ide: + +Install and run the IDE +----------------------- + +See the :ref:`IDE installation page <maple-ide-install>` for instructions. + +.. _maple-quickstart-compile-blinky: + +Compile a program! +------------------ + +Let's load up a simple example program that blinks the status LED. +From the File menu, select Examples > Digital > Blink: + +.. image:: /_static/img/blinky.png + :align: center + :alt: Click "Blink" + +Next, select Tools > Board > "LeafLabs Maple ... to Flash", where +"..." depends on the board you're using. + +.. image:: /_static/img/blinky-to-flash.png + :align: center + :alt: Upload to Flash + +.. note:: + + You have the choice between Flash and RAM programming. Flash saves + the program into permanent Flash memory. RAM simply puts the + compiled program into the processor's built-in RAM. + + Flash memory is larger, and is the only option for permanently + uploading a program. Programming to RAM is faster to upload, and a + buggy program can be wiped away with a simple reset. + +.. image:: /_static/img/verify_button.png + :align: left + :alt: Verify button + +Now press the "Verify" button (the "play" symbol; see image at left) +to compile the code. Some output should scroll by in the bottom +window, and then a confirmation message will appear: + +.. image:: /_static/img/verify-success.png + :align: center + :alt: Code verified successfully. + +.. _maple-quickstart-upload: + +Upload that program! +-------------------- + +Now it's time to plug in your Maple. Use a USB Mini-B cable (mini, +not micro). + +On the Maple, make sure that the :ref:`power source jumper +<maple-powering>` is on the USB header first (the same goes for Maple +Native). We ship Maples with the power source jumper configured that +way, so you shouldn't have to do anything. For reference, it should +look like this (don't worry if a jumper is hanging half off of the +CHRG header): + +.. image:: /_static/img/plugged-in-maple.png + :align: center + :alt: Correctly plugged in Maple + +.. note:: + + On OS X, a network interface dialog will pop up every time you plug in + the board. + + .. image:: /_static/img/osx-unconfigured-popup.png + :align: center + :alt: Unconfigured modem popup + + If you click "Network Preferences..." and accept the default ("Not + Configured"), the dialog won't pop up and everything will work fine. + That is, from this window, click "Apply": + + .. image:: /_static/img/osx-network-prefs-unconfigured.png + :align: center + :scale: 75% + :alt: Click "Apply" + +If all systems are go, select your board's serial port in the Tools > +Serial Port menu. It will appear as something like :file:`COMx`, +:file:`/dev/ttyACMx`, or :file:`/dev/tty.usbmodemxxxxx`, depending on +your platform, like so: + +Windows XP: + +.. image:: /_static/img/serial-port-win.png + :align: center + :alt: Board type and serial port for Windows XP + +Linux: + +.. image:: /_static/img/serial-port-ubuntu.png + :align: center + :alt: Board type and serial port for Linux + +OS X: + +.. image:: /_static/img/serial-port-mac.png + :align: center + :alt: Board type and serial port for the OS X + +Then press the "Upload" button to upload your program over USB. + +.. image:: /_static/img/upload-button.png + :align: center + :alt: Click the "Upload" button + +You should see some text and a progress bar flash by in the status +window of the IDE, then some quick blinking patterns, followed a +constant blinking on and off. Congratulations! You've successfully +uploaded your first program to your Maple. + +The built-in status LED should blink in a short pattern every time the +board is plugged in, reset, or reprogrammed. If it ever starts +throbbing in a smooth, even pattern, then you've got a problem; see +this :ref:`troubleshooting item <troubleshooting-throb>` for help. + +Next, go ahead and modify the file a little bit. If you change the +number in the ``delay(1000);`` lines, the speed of the blink will +change. The number is a time in milliseconds to pause before +continuing with the program, so by default, the LED will be on for 1 +second, then off for 1 second, etc. Any time you make any changes, go +through the same Verify and Upload process to upload the new version +of your program to your Maple. + +.. warning:: + + The uploading step is the most common source of problems, + especially on Windows. + + The situation is much improved over the past, but if you have + trouble, try doing things again, unplugging your Maple and plugging + it back in, using :ref:`perpetual bootloader mode + <troubleshooting-perpetual-bootloader>`, or restarting the + IDE. + + If nothing works, please report the problem in the `forum`_. + +.. _maple-quickstart-serial-port: + +Use the serial port monitor! +---------------------------- + +As a last step to make sure everything has been configured correctly, +let's upload a "Hello, world!" program that will send text from the +board back to the IDE over the USB connection. + +From the File menu, select Examples > Stubs > HelloWorld (similarly to +how you selected the Blink program), and make sure the correct board +and serial port targets are selected from the Tools menu. + +Open the Serial Monitor window (on the far right of the toolbar). Then +go back to the code editing window and upload your program. You should +get text spit at you over the serial monitor right after the program +is uploaded. Shout back! We can hear you! + +Go forth exuberantly! +--------------------- + +We really hope you got this far and didn't frown or make a bitter +lemon face getting here. Where you go now is up to you: perhaps you've +got some crazy project cooking, or a longer tutorial to work through, +or maybe now is a good time for a trip to the kitchen for a delicious +`sandwich <http://everything2.com/title/Velvet+Elvis>`_. + +If you blew through this guide and are the kind of person who drinks +their coffee straight, has more than a 100 lines of vim or emacs +customization, and doesn't even have a mouse plugged into their +computer, you may want to look at the :ref:`Unix toolchain quickstart +<unix-toolchain>` guide. It's the tutorial for getting working with +your old friends :command:`make`, :command:`gcc`, and :command:`jtag`. + +Let us know what you come up with! Reach us at `leaflabs +<http://twitter.com/#!/leaflabs>`_ on Twitter, post in the `forum`_, +post on `our wiki's Projects page +<http://wiki.leaflabs.com/index.php?title=Projects>`_, track us down +in the real world, whatever. We love projects! diff --git a/docs/source/prolog.rst b/docs/source/prolog.rst new file mode 100644 index 0000000..8606555 --- /dev/null +++ b/docs/source/prolog.rst @@ -0,0 +1,8 @@ +.. Additions to this file will be included at the beginning of every +.. .rst file. DO NOT USE IT to insert a header; this is not +.. recommended by the Sphinx people, who have other ways of doing it. + +.. Common substitutions +.. |vcc| replace:: V\ :sub:`CC` +.. |vdda| replace:: V\ :sub:`DDA` +.. |i2c| replace:: I\ :sup:`2`\ C diff --git a/docs/source/pwm.rst b/docs/source/pwm.rst new file mode 100644 index 0000000..421229d --- /dev/null +++ b/docs/source/pwm.rst @@ -0,0 +1,103 @@ +.. _pwm: + +PWM +=== + +Pulse Width Modulation (PWM) is a basic technique to create repeated square +waves (digital high/low voltage transitions) of user defined length +and duty cycle. It can be used as a way to encode an "analog" signal +on a single digital (high/low) line using the time between transitions +("pulse width") as the variable; this technique is commonly used to +send servo position and motor speed commands. Another use is to use to +the ratio of "high" and "low" time to approximate a voltage output; +this technique can be used to dim an LED or even (with careful +filtering) generate audio waveforms. + +.. contents:: Contents + :local: + +Overview +-------- + +.. FIXME [0.1.0] More information about how timer channels drive PWM + +Each PWM output is driven by an output channel connected to one of 4 +timers. Some configuration, such as the clock rate or prescaling, +must be common to the entire timer; see the :ref:`timer documentation +<timers>` for more information. See your board's :ref:`pin mapping +tables <gpio-pin-maps>` to track down the correspondence +between timer channels and GPIO pins. + +Background +---------- + +In its simplest form, the device is a single counter with two +variables. The counter starts at zero, and the output starts at +"high". The counter increments every clock cycle until it reaches the +first variable number, at which point the output goes "low". The +counter continues incrementing until it reaches the second variable at +which point the output goes "high" again and the counter resets to +zero. The time spent with output high is called the **pulse duration** +or **duty**; the total time before repeat is the **period**. + +This simple functionality could be approximated in software by setting +a GPIO high or low, but the beauty of PWM is that user code simply has +to configure the device and set the two variables and the device will +function on its own; no further microprocessor cycles will be +consumed, and a repeated high/low waveform will spew out. + +The Maple has 16-bit PWM resolution, which means that the counter and +variables can be as large as 65535, as opposed to 255 with 8-bit +resolution. With a 72MHz clock rate, a PWM output could have maximum +period of about one millisecond; using a :ref:`prescaler +<lang-hardwaretimer-setprescalefactor>` (clock divider) in front of +the counter can increase this maximum period. Setting the +:ref:`period <lang-hardwaretimer-setperiod>` to something other than +the maximum value gives further control over the total length of the +waveform. However, this effectively limits the resolution with which +the duty can be modified: the duty must be less than or equal to the +period. + +Here are some commonly used PWM configurations (note that servos are +notoriously variable, especially the lower cost models): + ++-------------+----------+-----------+---------+---------------+------+ +|**Purpose** |**Period**|**Duty** |Prescaler|Period |Duty | +| |(ms) |(ms) | | | | ++=============+==========+===========+=========+===============+======+ +|LED throb |0.020 |0--0.020 |1 (none) |65535 (default)|0--767| +| | | | | | | ++-------------+----------+-----------+---------+---------------+------+ +|Servo control|20 |1.25 (0°) |21 |65535 (default)|4096 | +| | | | | | | +| | |1.50 (90°) |21 |65535 (default)|4915 | +| | | | | | | +| | |1.75 (180°)|21 |65535 (default)|5734 | +| | | | | | | ++-------------+----------+-----------+---------+---------------+------+ + +Function Reference +------------------ + +- :ref:`lang-pinmode` +- :ref:`lang-pwmwrite` +- :ref:`Timer API<lang-hardwaretimer>` (especially :ref:`setOverflow() + <lang-hardwaretimer-setoverflow>`, :ref:`setPrescaleFactor() + <lang-hardwaretimer-setprescalefactor>`, and :ref:`setPeriod() + <lang-hardwaretimer-setperiod>`). +- :ref:`Timers reference <timers>`. + +Recommended Reading +------------------- + +* `Wikipedia Article on Pulse-width modulation + <http://en.wikipedia.org/wiki/Pulse-width_modulation>`_ +* `Arduino tutorial on PWM <http://www.arduino.cc/en/Tutorial/PWM>`_ +* `Secrets of Arduino PWM + <http://www.arcfn.com/2009/07/secrets-of-arduino-pwm.html>`_ by Ken + Shirriff +* `So You Want To Use PWM, Eh? <http://www.nlvocables.com/blog/?p=188>`_ at Non-Lexical Vocables +* STMicro documentation for STM32F103RB microcontroller: + + * `Datasheet <http://www.st.com/web/en/resource/technical/document/datasheet/CD00161566.pdf>`_ (pdf) + * `Reference Manual <http://www.st.com/st-web-ui/static/active/en/resource/technical/document/programming_manual/CD00228163.pdf>`_ (pdf) diff --git a/docs/source/spi.rst b/docs/source/spi.rst new file mode 100644 index 0000000..13c4c59 --- /dev/null +++ b/docs/source/spi.rst @@ -0,0 +1,30 @@ +.. _spi: + +===== + SPI +===== + +The Serial Peripheral Interface Bus (SPI) is a serial data transfer +protocol useful for interacting with a wide variety of hardware +peripherals. + +The public libmaple API for managing the SPI ports is the +:ref:`HardwareSPI <lang-hardwarespi>` class. + +Recommended Reading +------------------- + +* `Wikipedia Article on Serial Peripheral Interface Bus (SPI) + <http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus>`_ + +* `Arduino reference on SPI + <http://arduino.cc/en/Reference/SPI>`_ + +* `Hardcore SPI on Arduino <http://web.archive.org/web/20100522034122/http://klk64.com/arduino-spi/>`_ by kik64 + +* ST Documentation: + + * Reference Manual `RM0008 + <http://www.st.com/web/en/resource/technical/document/reference_manual/CD00171190.pdf>`_ + (PDF), Chapter 25, "Serial Peripheral Interface" + diff --git a/docs/source/stm32.rst b/docs/source/stm32.rst new file mode 100644 index 0000000..d918655 --- /dev/null +++ b/docs/source/stm32.rst @@ -0,0 +1,87 @@ +.. _stm32: + +Introduction to STM32 +===================== + +.. FIXME [v0.0.13] Stub page. + +Every Maple board is powered by an STM32 microcontroller (the chip +which controls all of the pins). Once you're comfortable using your +Maple, you'll probably start to get curious about what's going on +under the hood. This page is a good place to begin. It includes an +overview of the STM32, and helps you make sense of the sometimes +dizzying array of features, libraries, and documentation that are +available to you. + +The world of the STM32 is a big one, and it's only getting bigger. +With literally thousands of pages of manuals, datasheets, application +notes, etc. available for every STM32 microcontroller, and a huge +variety of categories and subcategories of STM32s available to choose +from, it's easy to get confused or feel daunted about getting started. +Don't panic! We've got `your towel +<http://en.wikipedia.org/wiki/Know_where_one%27s_towel_is#Knowing_where_one.27s_towel_is>`_ +right here. + +.. contents:: Contents + :local: + +.. _stm32-general: + +General Information +------------------- + +- Description of the history and present state of the STM32 line. ARM + Cortex-M series etc. + +- Introduction and pointers to ARM Cortex-M docs and other good books + on the subject. + +- Pointers to ST reference manuals. Note that the appropriate + reference manual for each board is always documented in that board's + hardware page. + +.. _stm32-series: +.. _stm32-series-f1-lines: + +STM32 Series +------------ + +- Describe families, F1 lines, etc. + +- Describe how a product name tells you what you need + +ST's Documentation +------------------ + +- Classes of documentation: product flyer, datasheet, reference + manual, programming manual, application note. + +.. _stm32-registers: + +Registers and Register Maps +--------------------------- + +- General purpose registers vs. peripheral registers. + +Perhaps you haven't read it in detail, but maybe you've at least +thumbed through a few of the sections, trying to gain some +understanding of what's going on. If you've done that (and if you +haven't, just take our word for it), then you know that underneath the +covers, *everything* is controlled by messing with bits in the +seemingly endless collections of registers specific to every +peripheral. The :ref:`USARTs <usart>` have data registers; (some of +the) the :ref:`timers <timers>` have capture/compare registers, the +:ref:`GPIOs <gpio>` have output data registers, etc. + +- Peripheral register maps; how they're duplicated for each peripheral + +- Portability concerns across series + +.. _stm32-libmaple-support: + +``libmaple`` STM32 support +-------------------------- + +- Descriptions of libmaple's present support for the STM32 line + (i.e. currently performance-line only; update when the F2 branch is + ready to merge into master etc.). diff --git a/docs/source/systick.rst b/docs/source/systick.rst new file mode 100644 index 0000000..afc8d09 --- /dev/null +++ b/docs/source/systick.rst @@ -0,0 +1,15 @@ +.. _systick: + +SysTick +======= + +.. TODO Recommended reading and more content. + +The SysTick peripheral provides a timer which :ref:`libmaple` uses to +keep track of the board's uptime. + +Library Documentation +--------------------- + +See :ref:`libmaple-systick` for more information on library support +for interfacing with the SysTick peripheral. 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. diff --git a/docs/source/troubleshooting.rst b/docs/source/troubleshooting.rst new file mode 100644 index 0000000..4d7cbb0 --- /dev/null +++ b/docs/source/troubleshooting.rst @@ -0,0 +1,258 @@ +.. highlight:: sh + +.. _troubleshooting: + +Troubleshooting +=============== + +This page documents common problems and their solutions. + +.. contents:: Contents + :local: + +=================== + Hardware problems +=================== + +.. _troubleshooting-throb: + +The LED is throbbing and my program is stopped! +----------------------------------------------- + +The LED throbs when there has been a failed software :ref:`ASSERT() +<lang-assert>` or some other error. + +In the case of a failed assertion, a first debugging step you can take +is to find out the file and line where the failed assertion took place +(for instructions on this, see the ``ASSERT()`` documentation linked +to above). This may give you some clue about the source of the error. + +:ref:`libmaple` often uses ``ASSERT()`` to halt immediately when it +detects that something has gone wrong, so if you're not using +assertions, then what's probably happening is that some bug is causing +the failed ``ASSERT()`` lower down. + +If it's not a failed assertion, then you're likely looking at +something like a `hard fault +<http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0337e/ch05s12s01.html>`_. + +There are a few issues with the bootloader which mean you might not be +able to upload your program when this happens. You can still +reprogram by using :ref:`perpetual bootloader mode +<troubleshooting-perpetual-bootloader>`. + +My board is bricked! I can't upload via the bootloader no matter what! +---------------------------------------------------------------------- + +Don't panic. First, make sure that the board is plugged in correctly +for program upload, using the instructions given in the +:ref:`quickstart <maple-quickstart-upload>`. If that doesn't work, +try using :ref:`perpetual bootloader mode +<troubleshooting-perpetual-bootloader>`. + +If that doesn't work, then you've got a problem. All is not lost, +however! You can always try to :ref:`re-flash the bootloader +<bootloader-reflashing>` over serial (or :ref:`JTAG <jtag>`). + +If your board really is bricked, and you think it's our fault, +`contact us <http://leaflabs.com/contact>`_\ ! + +My 5v peripheral doesn't work! (I2C, SPI, USART, etc) +----------------------------------------------------- + +Yup, the Maple is a 3.3v board. You may need to use a level +converter. See the :ref:`Arduino Compatibility +<arduino-compatibility>`, :ref:`GPIO <gpio>`, or other :ref:`hardware +specific documentation <index-hardware>` for more information. + +The reset and D38/serial buttons don't seem to work reliably! +------------------------------------------------------------- + +A few Maple Rev3 boards shipped in May-June 2010 may have had +unreliable buttons; see the :ref:`Maple Errata +<maple-rev3-bad-buttons>` for details. `We're happy to replace these +for you <http://leaflabs.com/contact>`_\ ! + +.. _troubleshooting-ide-install: + +======================= + Installation problems +======================= + +I don't have root/administrator access! +--------------------------------------- + +There are probably hacks or work-arounds to getting programs uploaded +without higher level system permissions. If you can access USB +character devices (ACM or ttyUSB style), you should be able to +communicate with the Maple and reprogram using an FTDI converter and +the serial bootloader, but we haven't tried. + +.. TODO: be more helpful + +[Linux] I don't use udev! +------------------------- + +There is probably a simple way to get autoconfiguration working with +devfs; in the meantime, you could try running the entire IDE as root. + +.. TODO: be more helpful + +.. _troubleshooting-ide-usage: + +============== + IDE problems +============== + +[Mac OS X] The "Board" and "Serial Port" menu items are missing! +---------------------------------------------------------------- + +Sometimes this happens if you try to compile or upload without having +a board selected. The work-around is to restart the IDE. Mysterious! + +.. _troubleshooting-compilation: + +========================== + Common compiler problems +========================== + +``NullPointerException`` +------------------------ + +A classic! Make sure you have selected a board from the pulldown menu. + +``undefined reference to setup()/loop()`` +----------------------------------------- + +Your sketch/program either does not include one of the :ref:`setup() +<lang-setup>` or :ref:`loop() <lang-loop>` functions, or it was not +found by the compiler. Your program must include both ``void setup()`` +and ``void loop()`` functions; they don't have to do anything, but +they **must** be there. + +You can start with an example program (to see one in the IDE, click on +File > Examples > Stubs > BareMinimum) to get the basic structure. +See also the :ref:`language <language>` documentation. + +This is a common error when your entire sketch is blank. + +``error: 'Serial' was not declared in this scope`` +-------------------------------------------------- + +The classic Arduino has only one USART device and uses the unique name +"Serial" to control it. Larger devices like the Arduino Mega and the +Maple have multiple USARTS referred to as ``Serial1``, ``Serial2``, +etc. You probably want ``Serial2`` on the Maple; that's the one +connected to pins D0 and D1. See also the :ref:`USART docs <usart>`. + +``File(s) not found`` +--------------------- + +There is an intermittent bug with the temporary directory build system +that on occasion will lose many of the ``#include``\ d libmaple +files. If you recompile everything, it should be fine. + +.. _troubleshooting-upload: + +====================== +Common upload problems +====================== + +My program is too large! +------------------------ + +First, make sure you're using the Flash target instead of RAM; there +is several times more Flash memory available for user programs. + +``No DFU capable USB device found`` +----------------------------------- + +This probably means the Maple isn't plugged in or powered on. Try +unplugging and plugging back in, or pressing the RESET button. + +This can also happen if you disable the USB peripheral, e.g. using +:ref:`SerialUSB.end() <lang-serialusb-end>`. + +I have multiple boards plugged in; how do I know which one will get programmed? +------------------------------------------------------------------------------- + +Because the Maple IDE uses DFU to upload programs, you can't select a +particular board to upload to. There's no solution to this problem +for now: you'll have to just plug in your boards one at a time. If +this is a real problem, let us know, and we'll see if we can come up +with a better solution. + +My Flash programs don't seem to stick; they behave like they are RAM! +--------------------------------------------------------------------- + +If you have uploaded a program to RAM, this will take priority over +any program subsequently uploaded to flash. We'll be removing this +bug in a later version of the bootloader. For now, you can fix this +by unplugging your Maple to clear the contents of RAM, then plugging +it back in. + +If you are using the :ref:`Unix toolchain <unix-toolchain>`, Make sure +you :command:`make clean` when switching between Flash and RAM +targets; our Makefile isn't smart enough to rebuild everything for the +new target. + +My code uploads, but it doesn't work! +------------------------------------- + +Are you sure you have the right board selected? (Maple vs. Maple Mini, +etc.) + +.. _troubleshooting-shell: + +=================== +Command-Line Issues +=================== + +[Linux] ``cdc_acm 3-1:1.0: no more free acm devices`` +----------------------------------------------------- + +This is a nasty one! It means that all 32 possible CDC_ACM serial +devices (:file:`/dev/ttyACM25`, etc.) have been used up. + +The usual cause is using a serial port monitor and not closing it +before restarting the board or uploading a new program. The operating +system doesn't like that, and locks up that device. After reset, the +board comes back up as a new device. If you develop heavily and don't +restart, you'll blow right through all 32 devices. + +The lazy solution is to always close the monitor before restarting, +and if you get this error in :file:`dmesg` after a dfu-util "Not +Found" error, restart you machine. + +The hacker solution is to restart your cdc_acm kernel module. On +Ubuntu 9.10, this goes a little something like:: + + $ sudo rmmod cdc-acm + $ sudo insmod /lib/modules/2.6.31-20-generic/kernel/drivers/usb/class/cdc-acm.ko + +.. _troubleshooting-tips-tricks: + +=============== +Tips and Tricks +=============== + +.. _troubleshooting-perpetual-bootloader: + +Perpetual Bootloader Mode +------------------------- + +In this mode, Maple stays a DFU device and does not jump to user code +until the next reset. This is useful for guaranteeing that your Maple +will be available for reprogramming. + +To put your Maple (or other Maple board) into perpetual bootloader mode: + +#. Plug your board into the USB port. + +#. Hit the reset button (it's the button labeled RESET). Notice that + your board blinks quickly 6 times, then blinks slowly a few more + times. + +#. Hit reset again, and this time push and hold the other button + during the 6 fast blinks (the normal button is labeled BUT). You + can release it once the slow blinks start. diff --git a/docs/source/unix-toolchain-linux-setup.rst b/docs/source/unix-toolchain-linux-setup.rst new file mode 100644 index 0000000..c1333e1 --- /dev/null +++ b/docs/source/unix-toolchain-linux-setup.rst @@ -0,0 +1,203 @@ +.. highlight:: sh + +.. _unix-toolchain-linux-setup: + +Unix Toolchain Linux Setup +========================== + +This page contains instructions for setting up a Linux computer for +use with the :ref:`Unix toolchain <unix-toolchain>`. (Setup +instructions for :ref:`other operating systems <toolchain-setup>` are +also available.) + +These instructions have been tested successfully on: + +- Ubuntu 10.04 and 12.04 (32- and 64-bit) +- Fedora 17 (64-bit) +- Debian Wheezy 64-bit + +Generic instructions for other distributions are also provided. Please +`contact`_ us with any updates for distros not already covered! + +.. contents:: Contents + :local: + +Collect and Install Tools +------------------------- + +First, you'll need some tools. + +.. warning:: Due to firmware bugs in our :ref:`bootloader + <bootloader>`, you must use recent versions of ``dfu-util``, or + uploads will not work. ``dfu-util`` versions 0.6 and greater + should work. + +**Debian-based distributions (Debian, Ubuntu, Mint, etc.)**: + + Install mandatory and optional tools with :: + + $ sudo apt-get install build-essential git-core screen dfu-util python python-serial + + On *64-bit distros only*, you will also need to install some 32-bit + libraries needed by the LeafLabs-supported :ref:`ARM GCC toolchain + <arm-gcc>` with :: + + # 64-bit systems only! + $ sudo apt-get install ia32-libs + + # As of Ubuntu 13, you should do this instead: + $ sudo apt-get install lib32z1 lib32ncurses5 lib32bz2-1.0 + + You may also need to remove `brltty <http://mielke.cc/brltty/>`_ + with :: + + # Optional + $ sudo apt-get remove brltty + + Brltty provides braille access to the console. It has been reported + to cause conflicts with Maple. + +**Red Hat-based distributions (RHEL, Fedora, Centos, etc.)**: + + Install mandatory and optional tools with :: + + $ sudo yum install screen git python pyserial dfu-util make + + On *64-bit distros only*, you will also need to install 32-bit + libraries needed by the LeafLabs-supported :ref:`ARM GCC toolchain + <arm-gcc>` with :: + + # 64-bit systems only! + $ sudo yum install glibc.i686 + + You may also need to remove `brltty <http://mielke.cc/brltty/>`_ + with one of these:: + + # Optional, 64-bit systems: + $ sudo yum erase brltty.x86_64 + + # Optional, 32-bit systems: + $ sudo yum erase brltty.i686 + + Brltty provides braille access to the console. It has been + reported to cause conflicts with Maple. + +**Other Linux distributions**: + + On other distributions, you'll need to figure this out for yourself + (please `contact`_ us if you have instructions for distros not + covered here!). + + Mandatory tools: + + * `Git`_ is a distributed version control system. We use it to track + our source code. + + * `dfu-util`_ is a tool from the `OpenMoko`_ project. It is used to + upload programs to the Maple over USB. + + * `Make <http://www.gnu.org/software/make/>`_ is used to direct + compilation. + + * `Python`_ is a programming language. Our reset script, which sends + control signals to the board which cause it to to reset and enter + the :ref:`bootloader <bootloader>`, is written in Python (and + works with Python 2 or 3). Most Linux distributions these days + include Python by default. + + * `PySerial`_ is a Python library for interacting with serial port + devices. It's needed by our reset script. PySerial can also be + installed with `easy_install`_. + + Optional tools: + + * `screen <http://www.gnu.org/s/screen/>`_ is a screen manager used + here to connect to serial port devices. (Some popular + alternatives are `Minicom + <http://alioth.debian.org/projects/minicom/>`_ and `Kermit + <http://www.kermitproject.org/>`_). + +Fetch ``libmaple`` and Compiler Toolchain +----------------------------------------- + +First, make a Git clone of :ref:`libmaple`:: + + $ cd ~ + $ git clone git://github.com/leaflabs/libmaple.git libmaple + +Next, download the `Linux ARM GCC toolchain +<http://static.leaflabs.com/pub/codesourcery/gcc-arm-none-eabi-latest-linux32.tar.gz>`_ +you'll use to build your programs. Extract the archive into a +directory named :file:`arm`. Put the resulting :file:`arm/bin` +subdirectory somewhere in your ``PATH``. For example, if you have +`wget <http://www.gnu.org/software/wget/>`_ installed, you can run:: + + $ cd ~/libmaple + $ wget http://static.leaflabs.com/pub/codesourcery/gcc-arm-none-eabi-latest-linux32.tar.gz + $ tar xvf gcc-arm-none-eabi-latest-linux32.tar.gz + $ export PATH=$PATH:~/libmaple/arm/bin + +You can check that this worked by entering ``arm-none-`` and hitting +tab to auto-complete; your shell should show a bunch of results. After +you're done, you'll probably want to update your shell startup script +so the :file:`arm/bin` directory stays in your ``PATH``. + +.. _toolchain-udev: + +Install udev Rules +------------------ + +From the libmaple directory, copy our udev rules [#fudev]_ to +``/etc/udev/rules.d``:: + + $ sudo cp support/scripts/45-maple.rules /etc/udev/rules.d/45-maple.rules + +Then restart udev. + +**Ubuntu (NOT Debian)**: + + Make sure you are in the plugdev group (e.g. by running ``$ groups`` + and seeing if the output includes "plugdev"). If not, add yourself + to plugdev with :: + + $ sudo usermod -a -G plugdev $USER + + then log out and log back in. + + After that's done, restart udev:: + + $ sudo restart udev + +**Debian (NOT Ubuntu)**: + + Make sure you're in the dialout group. If not, add yourself with :: + + $ sudo usermod -a -G dialout $USER + + then log out and log back in. + + After that's done, restart udev:: + + $ sudo /etc/init.d/udev restart + +**Red Hat-based distros**: + + :: + + $ udevadm control --reload-rules + +After restarting ``udev``, you'll need to unplug and re-plug your +Maple. + +So far, so good? +---------------- + +Great! Move on by :ref:`compiling a sample program <toolchain-test>`. + +.. rubric:: Footnotes + +.. [#fudev] As a security precaution on Linux, unknown USB devices can + only be accessed by root. This udev script identifies the Maple + based on its vendor and product IDs, mounts it to + :file:`/dev/maple`, and (for Debian-based distros) grants + read/write permissions to the ``plugdev`` group. diff --git a/docs/source/unix-toolchain-osx-setup.rst b/docs/source/unix-toolchain-osx-setup.rst new file mode 100644 index 0000000..01b9e2c --- /dev/null +++ b/docs/source/unix-toolchain-osx-setup.rst @@ -0,0 +1,132 @@ +.. highlight:: sh + +.. _unix-toolchain-osx-setup: + +Unix Toolchain OS X Setup +========================= + +This page contains instructions for setting up an OS X computer for +use with the :ref:`Unix toolchain <unix-toolchain>`. (Setup +instructions for :ref:`other operating systems <toolchain-setup>` are +also available.) + +These instructions have been tested successfully on OS X 10.6.4 and +10.8.1. + +.. contents:: Contents + :local: + +Collect and Install Tools +------------------------- + +First, you'll need some tools. [#fpackman]_ + +* `XCode <https://developer.apple.com/xcode/>`_: Provides compilers + and other basic tools of the trade. XCode seems to only be available for + those with Apple IDs through the Mac App Store. If you'd rather not go + through that mechanism, you can probably get by with just a `make + <http://www.gnu.org/software/make/>`_ binary, but you're on your own. + +* `Git`_: All of our code is tracked by a distributed versioning + system called Git. A `Mac installer + <http://code.google.com/p/git-osx-installer/downloads/list?can=3>`_ + is available. + +* `dfu-util`_: A tool from `OpenMoko`_ that we use to upload programs + to the Maple over USB. + + .. warning:: Due to firmware bugs in our :ref:`bootloader + <bootloader>`, you must use recent versions of ``dfu-util``, or + uploads will not work. ``dfu-util`` versions 0.6 and greater + should work. + + If you prefer to compile from source, OpenMoko provides instructions + for `building dfu-util on OS X + <http://wiki.openmoko.org/wiki/Dfu-util#Mac>`_. + + If you're in a hurry, you can use the dfu-util binary bundled with + `OpenMoko Flasher + <http://www.handheld-linux.com/wiki.php?page=OpenMoko%20Flasher>`_. To + do this, first `download OpenMoko Flasher + <http://projects.goldelico.com/p/omflasher/downloads/>`_, then move + it to your :file:`/Applications` folder (or wherever you + like). Let's say you save it as :file:`/Applications/OpenMoko + Flasher.app`. Then the ``dfu-util`` binary resides in + + :file:`/Applications/OpenMoko Flasher.app/Contents/Mac OS/dfu-util` + + To run it from the command line, make a symbolic link to the binary + from some place on your ``PATH``:: + + $ ln -s /Applications/OpenMoko\ Flasher.app/Contents/Mac\ OS/dfu-util \ + /somewhere/on/your/PATH/dfu-util + + .. note:: + + Copying the binary won't work, as it relies on dynamically linked + libraries found elsewhere in the .app bundle. + + To make sure this worked, plug in your Maple, put it into + :ref:`perpetual bootloader mode + <troubleshooting-perpetual-bootloader>` (press RESET, then quickly + press and hold BUT for several seconds), and run :: + + $ dfu-util -l + + The output should look like this:: + + Found DFU: [0x1eaf:0x0003] devnum=0, cfg=0, intf=0, alt=0, name="DFU Program RAM 0x20000C00" + Found DFU: [0x1eaf:0x0003] devnum=0, cfg=0, intf=0, alt=1, name="DFU Program FLASH 0x08005000" + +* `PySerial`_: our reset script (which sends control signals over the + USB-serial connection to restart and enter the bootloader) is + written in Python, and requires the PySerial library. Download and + extract the `latest version + <http://pypi.python.org/pypi/pyserial>`_, then install with :: + + $ cd /path/to/pyserial-x.y + $ python setup.py build + $ sudo python setup.py install + + PySerial is also available via `easy_install`_, so if you're + comfortable using that, you could alternatively install it with :: + + $ easy_install pyserial + +Fetch ``libmaple`` and Compiler Toolchain +----------------------------------------- + +First, make a `Git`_ clone of :ref:`libmaple`:: + + $ cd ~ + $ git clone git://github.com/leaflabs/libmaple.git + +Next, `download the cross-compilers +<http://static.leaflabs.com/pub/codesourcery/gcc-arm-none-eabi-latest-osx32.tar.gz>`_ +you'll use to build libmaple and your own programs. (These are just +special-purpose versions of :ref:`GCC <arm-gcc>`). + +Let's say you saved these into +:file:`~/Downloads/gcc-arm-none-eabi-latest-osx32.tar.gz`. Then unpack +the archive and tell the shell about its contents with:: + + $ cd ~/Downloads + $ tar -xvf gcc-arm-none-eabi-latest-osx32.tar.gz + $ mv arm ~/libmaple/arm + $ export PATH=$PATH:~/libmaple/arm/bin + +After that's done, update your shell startup script so +:file:`~/libmaple/arm/bin` stays in your ``PATH``. + +So far, so good? +---------------- + +Great! Move on by :ref:`compiling a sample program <toolchain-test>`. + +.. rubric:: Footnotes + +.. [#fpackman] Some of these software packages might be available on + `MacPorts <http://www.macports.org/>`_ or `Homebrew + <http://mxcl.github.com/homebrew/>`_. The author had some bad + experiences with MacPorts a few years ago, though, and hasn't + touched a package manager on OS X since. Your mileage may vary. diff --git a/docs/source/unix-toolchain-win-setup.rst b/docs/source/unix-toolchain-win-setup.rst new file mode 100644 index 0000000..099e7fe --- /dev/null +++ b/docs/source/unix-toolchain-win-setup.rst @@ -0,0 +1,163 @@ +.. highlight:: sh + +.. _unix-toolchain-win-setup: + +Unix Toolchain Windows Setup +============================ + +This page contains instructions for setting up a Windows computer for +use with the :ref:`Unix toolchain <unix-toolchain>`. (Setup +instructions for :ref:`other operating systems <toolchain-setup>` are +also available.) + +These instructions have been tested successfully on Windows 7 Home +Premium. + +.. contents:: Contents + :local: + +Collect and Install Tools +------------------------- + +First, you'll need some tools. + +* `GitHub for Windows <http://windows.github.com/>`_: this is a GUI + for `Git`_, the version control system we use for :ref:`libmaple`. + + If you don't have one, you need to sign up for a (free) `GitHub + account <https://github.com/signup/free>`_. + + .. note:: If you use Git from the command line, you can clone + libmaple with:: + + $ git clone git://github.com/leaflabs/libmaple.git + + If you go this route, you don't need a GitHub account. + +* `Python`_: choose the **latest 2.7.x version**. (Python 3 works, but + you're on your own.) + +* `PySerial`_: Choose the latest **pyserial-x.y-win32.exe version**. + +Fetch ``libmaple`` and Compiler Toolchain +----------------------------------------- + +First, make a Git clone of the :ref:`libmaple` repository with the +following steps: + +1. **Run GitHub for Windows**, and **sign in** using your GitHub + account. +2. **Visit** `libmaple's GitHub page + <https://github.com/leaflabs/libmaple/>`_, and **sign in** to + GitHub in your web browser as well. +3. **Click on the "Clone in Windows" button** on libmaple's GitHub + page, which looks like this: + + .. figure:: /_static/img/github-clone-in-windows.png + + Your browser may prompt you about what to do when you click the + "Clone in Windows" button. Choose the option that launches the + GitHub for Windows application. + +Next, you'll need to get some cross-compilers and other tools for +building and uploading your programs: + +- `Download a .zip of the latest tools + <http://static.leaflabs.com/pub/codesourcery/gcc-arm-none-eabi-latest-win32.zip>`_. + +- Extract the .zip, and **move the extracted "arm" folder into the + libmaple repository's folder**. + + You can open the libmaple repository folder by right-clicking + libmaple in the main GitHub for Windows screen and choosing "open in + explorer": + + .. figure:: /_static/img/win7-github-open-in-explorer.png + :align: center + +Update your PATH +---------------- + +You'll next need to configure your system to use the various tools +you've downloaded and installed. Do that by adding the Python and +``arm\bin`` directories to your PATH environment variable. + +If you've never set environment variables before, this section +explains what to do. + +**Add Python to your PATH**: + + Start by navigating to the folder where Python is installed on your + system (this is probably ``C:\Python27``). Right click on the folder + address, then choose "Copy address as text": + + .. figure:: /_static/img/win7-copy-python-address.png + :align: center + + Next, open your environment variables window: from the Start/Windows + menu, right click on Computer, then choose Properties > Advanced + System Settings > Environment Variables. Under the "User variables + for YOUR_USERNAME", look for PATH. + + - If PATH is missing from the list, click "New...". + + Under "Variable Name", write PATH. Under "Variable value", paste + the Python address you just copied, and click OK. The result looks + like this: + + .. figure:: /_static/img/win7-python-path.png + :align: center + + - If PATH is present in the list, click on it and choose "Edit...". + + Go to the end of the "Variable value:" text box, type a semicolon + (the ``;`` character), and then paste the path you just + copied. Click OK. + + Test that this worked by running the Git Shell program that came with + GitHub for Windows, then running ``python`` at the command prompt. You + should get a Python interpreter that looks like this: + + .. figure:: /_static/img/win7-python-prompt.png + :align: center + + If that worked, then close the window. + +**Add compiler toolchain to your PATH**: + + Do this by adding the ``arm\bin`` directory (earlier instructions + had you move ``arm`` to the libmaple repository folder) to your PATH + environment variable in the same way you added Python. + + Copy the address of the ``arm\bin`` folder by right-clicking on it + after navigating to it: + + .. figure:: /_static/img/win7-copy-arm-bin-address.png + :align: center + + The PATH environment variable should exist from when you added + Python to it, so make sure you choose "Edit..." from the + environment variables window. Then paste the ``arm\bin`` address you + copied after typing a semicolon. The final result will look + something like this: + + .. figure:: /_static/img/win7-python-arm-bin-path.png + :align: center + + Click OK. + +So far, so good? +---------------- + +Great! Open a new Git Shell, then type this at the prompt and hit +return to get to the libmaple directory:: + + cd libmaple + +.. warning:: You must open a new Git Shell window. If you use a shell + that's already open, then the changes to PATH you just + made won't be available, and the instructions in the next + section won't work. + +Now you're ready to move on by :ref:`compiling a sample program +<toolchain-test>`. diff --git a/docs/source/unix-toolchain.rst b/docs/source/unix-toolchain.rst new file mode 100644 index 0000000..769b8ec --- /dev/null +++ b/docs/source/unix-toolchain.rst @@ -0,0 +1,375 @@ +.. highlight:: sh + +.. _unix-toolchain: + +=========================== + Unix Toolchain Quickstart +=========================== + +This is a tutorial for using a standard Unix toolchain (``make``, +``gcc``, etc.) with Maple. It's intended for C and C++ programmers +who want to use :ref:`libmaple` directly. If you're just beginning, we +recommend installing :ref:`Maple IDE <maple-ide-install>` instead. + +.. contents:: Contents + :local: + +Requirements +------------ + +We assume you've had success with the :ref:`Maple IDE <ide>` (this is +important on Windows, as this document doesn't cover :ref:`driver +installation <maple-ide-install-windows-drivers>`). + +At a minimum, you need: + +* Maple board +* Mini-B USB cable +* root (or Administrator) access to your computer. + +On Linux and OS X, you need to know how to use `bash +<http://www.gnu.org/software/bash/>`_, and how to edit your .bashrc. +Some experience using `GCC <http://gcc.gnu.org/>`_ and `make +<http://www.gnu.org/software/make/>`_ is recommended, but is not +required. + +.. _toolchain-linux-setup: +.. _toolchain-osx-setup: +.. _toolchain-win-setup: +.. _toolchain-setup: + +Setup +----- + +You first need to set up your computer by installing and configuring +various things. Don't fret! We've got detailed instructions, just for +you. + +* :ref:`Linux <unix-toolchain-linux-setup>` +* :ref:`OS X <unix-toolchain-osx-setup>` +* :ref:`Windows <unix-toolchain-win-setup>` + +Come back when you're ready. We'll wait. + +.. _toolchain-test: + +Test compilation +---------------- + +Test that you've installed all the compilation tools correctly by +running the following commands in your shell. + +Windows users: + + - Don't type the ``$``'s, just the parts that come after. + - First get to libmaple by opening a Git Shell, then running ``cd libmaple``. + - **Always type** ``cs-make`` **instead of** ``make``. + +Linux and OS X users: + + - Run these from the top-level libmaple directory. + +:: + + $ cp main.cpp.example main.cpp + $ make clean + $ make + +If all goes well, you should see a bunch of output, then something +like this:: + + Final Size: + text data bss dec hex filename + 13164 1704 552 15420 3c3c build/maple.elf + +Hurray! You've just compiled your first program for Maple. + +**Important: if you're not using Maple (Maple Mini, etc.), make sure +to read the following note before moving on**. + +You can now move on to :ref:`uploading a program <toolchain-upload>`, +or take a quick detour to learn :ref:`more about the build output +<toolchain-build-info>`. + +.. _toolchain-setting-board: + +.. note:: This tutorial assumes you're using a Maple. If you're + compiling for another board, you'll need to set a ``BOARD`` + environment variable appropriately. + + To get a list of values for ``BOARD``, run :: + + $ make list-boards + + For example, to compile for Maple Mini: + + * On OS X or Linux, run:: + + $ export BOARD=maple_mini + $ make + + * On Windows, set a new environment variable named ``BOARD`` to + value ``maple_mini``, then open a new Git Shell, and run ``cd + libmaple`` followed by ``cs-make`` as explained above. + + You can check that this worked by making sure that the final + program file is named ``build/maple_mini.elf`` instead of + ``maple.elf``:: + + Final Size: + text data bss dec hex filename + 16848 2696 704 20248 4f18 build/maple_mini.elf + + Other notes for OS X and Linux: + + - You can also use the following, but you'll need to write the + ``BOARD=maple_mini`` part every time you call ``make`` (for + ``make install``, etc.):: + + $ BOARD=maple_mini make + + - To make the board setting permanent, add this line to your + .bashrc:: + + export BOARD=maple_mini + +.. warning:: You must start from a clean build after each time you + change ``BOARD`` (advanced users: or ``MEMORY_TARGET``). For + example, if you compile a program for Maple, then you want to + compile another program for Maple Mini, you must run ``$ make + clean`` **before** you compile the second program. If you do not, + you will experience strange errors. + +.. _toolchain-build-info: + +Notes about the ``libmaple`` build +---------------------------------- + +These are just some miscellaneous notes that are good to know. Feel +free to skip reading this section. + +- The ``dec`` field at the end of the build output under ``Final + Size:`` gives the total program size in bytes. The ``text``, + ``data``, and ``bss`` fields respectively break down the size of the + program into `code <http://en.wikipedia.org/wiki/Code_segment>`_, + `initialized data <http://en.wikipedia.org/wiki/Data_segment>`_, and + `zero-valued data <http://en.wikipedia.org/wiki/.bss>`_. + +- The long list of object files above the ``Final Size`` shows similar + information on a per-file basis. You can use it to help slim down + programs that use too much space. + +- ``build/$BOARD.elf`` is the final build result (where ``BOARD`` is + ``maple``, ``maple_mini``, etc. :ref:`depending on your build + <toolchain-setting-board>`). + +- There are other files under ``build`` you may be interested in, like + disassembly and map files. + +- If you want quicker build times, you should check out our blog post, + `Making libmaple compile faster + <http://leaflabs.com/2012/08/2549/>`_. + +.. _toolchain-upload: + +Upload a program +---------------- + +Let's blow away the little example program and upload the interactive +test session to your Maple. This will let you interact with the Maple +over a :ref:`USB serial port <usb>`. + +* Linux: you need udev rules set up :ref:`as described in the setup + doc <toolchain-udev>`. + +* Windows: you need to :ref:`install the Maple's device drivers + <maple-ide-install-windows-drivers>`. + +* OS X: everything Just Works for you. Aren't you special? + +Plug in your Maple using a Mini-B USB cable, then run :: + + # Window users: as usual, use cs-make instead of make. + + $ cp examples/test-session.cpp main.cpp + $ make clean + $ make + $ make install + +A number of things can go wrong at this stage. Simple debugging steps +include using :ref:`perpetual bootloader mode +<troubleshooting-perpetual-bootloader>`, restarting the Maple a couple +times, ``make clean``, etc. If nothing works, the `forum`_ is your +friend. + +.. _toolchain-serialusb: + +Communicate over USB-Serial +--------------------------- + +Now let's try out the interactive test session. You need to connect +to the board's serial port device file. + +* Linux: this looks like :file:`/dev/ttyACM*`. +* OS X: it looks like :file:`/dev/tty.usbmodem*`. +* Windows: it will be :file:`COMx`, where ``x`` is some number. + +Try using one of these to find out which it is:: + + # Linux + $ ls /dev/ttyACM* + + # OS X + $ ls /dev/tty.usbmodem* + + # Windows, works from libmaple directory + $ python support/scripts/win-list-com-ports.py + +To open up a session on Linux or OS X, run :: + + $ screen /dev/ttyXXX + +(On Windows, you will need to use a separate program, such as Maple +IDE's serial console or `PuTTY +<http://www.chiark.greenend.org.uk/~sgtatham/putty/>`_.) + +``screen`` will present you an empty terminal. Your board is waiting +for you to send it a command. Type ``h`` to print a list of commands; +type any command's letter to run it. + +.. highlight:: none + +Example output (for Maple):: + + > u + Hello World! + > b + Board information + ================= + * Clock speed (MHz): 72 + * BOARD_LED_PIN: 13 + * BOARD_BUTTON_PIN: 38 + * GPIO information (BOARD_NR_GPIO_PINS = 44): + ADC pins (15): 0, 1, 2, 3, 10, 11, 12, 15, 16, 17, 18, 19, 20, 27, 28 + PWM pins (15): 0, 1, 2, 3, 5, 6, 7, 8, 9, 11, 12, 14, 24, 27, 28 + Used pins (7): 13, 38, 39, 40, 41, 42, 43`` + +.. highlight:: sh + +To exit the screen session, type :kbd:`C-a k` (control-a k) on Linux, +or :kbd:`C-a C-\\` (Control-a, followed by Control-backslash) on OS X, +and type ``y`` when prompted if you're sure. + +.. note:: + + Using ``screen`` sometimes messes up your terminal session on OS X. + If your shell starts acting funny after you exit ``screen``, you + should be able to fix it with :: + + $ reset && clear + + If that doesn't work, just close the Terminal window and open up a + new one. + +.. _toolchain-projects: + +Start your own project +---------------------- + +So everything worked, and you want to start your own project? Great! +There are two ways to go about it. + +If your project is small, all you have to do is replace +:file:`~/libmaple/main.cpp` with your own code, and you're free to use +``make`` and ``make install`` in the same way you did when you first +:ref:`uploaded a program <toolchain-upload>`. + +If you have a more complicated project, with its own Makefile and +multiple source files, or if you're using an IDE that creates its own +Makefile, you'll probably want to load libmaple from an archive (a +build-time library, not a DLL). + +To create an archive, use the ``library`` Makefile target:: + + $ cd ~/libmaple + $ make library + +This will produce a build-time library in the file +:file:`~/libmaple/build/libmaple.a`. To use it, make sure that you +link against that library, and that the libmaple sources are in your +include path. + +There is also a page on `starting a project with the Unix toolchain +<http://wiki.leaflabs.com/index.php?title=Starting_A_Project_%28No_IDE%29>`_ +on the `LeafLabs wiki <http://wiki.leaflabs.com>`_ that you may find +useful. + +Get updates +----------- + +We update libmaple fairly frequently with bugfixes and other +improvements. In order get access to these in your local copy of the +repository, you should periodically update it with:: + + $ cd ~/libmaple + $ git pull + +We do our best to keep the master libmaple branch on GitHub free from +broken or half-finished code, so don't be too scared running the +latest and greatest. If you do, please report any bugs or regressions! + +We keep releases of libmaple and the Maple IDE in lockstep, so any IDE +updates will have corresponding library updates. Our `blog +<http://leaflabs.com/blog/>`_ is the place to watch for major +releases; an `RSS feed <http://leaflabs.com/blog/feed/>`_ is +available. + +You can sign up for a free `GitHub <https://github.com/plans>`_ +account and `watch libmaple +<https://github.com/leaflabs/libmaple/watchers>`_ to receive +notifications about bleeding-edge development. + +.. _toolchain-openocd: + +(Optional) Upload/Debug with JTAG/SWD +------------------------------------- + +Advanced users will wish to use a JTAG (or SWD) dongle for uploading +and debugging their programs. A big advantage to this approach is that +it lets you use `GDB <http://www.gnu.org/software/gdb/>`_ to +single-step through your code, inspect variables, etc. + +You can build your projects for JTAG or SWD upload with the ``jtag`` +Makefile target. That is, instead of compiling with ``make``, compile +with :: + + # (This is equivalent to $ MEMORY_TARGET=jtag make) + $ make jtag + +Then use your favorite JTAG/SWD dongle and driver software to upload +the resulting program. An `ELF +<http://en.wikipedia.org/wiki/Executable_and_Linkable_Format>`_ +suitable for upload is in :file:`build/$BOARD.elf`; the raw binary you +can copy directly to address 0x0 is :file:`build/$BOARD.bin`. + +.. warning:: Uploading code built with the ``jtag`` target will + overwrite the :ref:`bootloader <bootloader>`. This is a good thing + -- since you're using another upload method, this lets you use the + Flash and RAM the bootloader ordinarily reserves for itself. You + can always :ref:`reflash the bootloader <bootloader-reflashing>` + later. + +While LeafLabs doesn't officially support any particular way of using +JTAG with Maple, there is a `JTAG How-To +<http://wiki.leaflabs.com/index.php?title=Maple_JTAG_How_To>`_ on the +`LeafLabs wiki <http://wiki.leaflabs.com>`_ that you may find useful. + +.. _toolchain-exuberantly: + +Go forth exuberantly! +--------------------- + +Let us know what you come up with! Mention `@leaflabs on Twitter +<http://twitter.com/#!/leaflabs>`_, post in the `forum`_, join the the +#leafblowers IRC channel on `freenode +<http://freenode.net/irc_servers.shtml>`_, whatever. We love projects! diff --git a/docs/source/usart.rst b/docs/source/usart.rst new file mode 100644 index 0000000..dbbc81c --- /dev/null +++ b/docs/source/usart.rst @@ -0,0 +1,62 @@ +.. _usart: + +USART +===== + +A USART is more commonly known a *serial port*. It's used to transmit +information between Maple and another device (like your computer, +another Maple, etc.). + +.. contents:: Contents + :local: + +.. _usart-circuit: + +Hardware/Circuit Design +----------------------- + +To use a serial port to communicate with an external serial device, +connect the TX pin to your device's RX pin, the RX to your device's TX +pin, and your Maple board's ground to your device's ground. + +.. warning:: Don't connect these pins directly to an RS232 serial + port; they operate at +/- 12V and can damage your board. + +Each LeafLabs board has at least 3 separate USART devices. In the most +simple use case, the RX and TX pins are used to send data at a +predetermined speed (or *baud rate*). Their usage is documented in +the :ref:`Serial Ports <lang-serial>` language reference page. + +Which pins correspond to the USART TX and RX pins are given on your +board's silkscreen, and also in the board-specific USART pin maps +available here: + +* :ref:`Maple <maple-usart-map>` +* :ref:`Maple RET6 Edition <maple-ret6-usart-map>` +* :ref:`Maple Mini <maple-mini-usart-map>` +* :ref:`Maple Native Beta <maple-native-b-usart-map>` + +If you use a particular serial port, you cannot also use its +communication pins for other purposes at the same time. + +Compatible Devices and Specifications +------------------------------------- + +We have successfully used the USART ports with an FT232R-based +USB-serial converter at up to 115200 baud. Higher speeds should +certainly be possible. + +Recommended Reading +------------------- + +* `Wikipedia article on Universal Asynchronous Receiver/Transmitter + (USART) + <http://en.wikipedia.org/wiki/Universal_asynchronous_receiver/transmitter>`_ +* `Arduino Serial reference + <http://arduino.cc/en/Reference/Serial>`_ +* ST `Reference Manual RM0008 + <http://www.st.com/web/en/resource/technical/document/reference_manual/CD00171190.pdf>`_ + (PDF), Chapter 27. +* `Serial and UART Tutorial + <http://www.freebsd.org/doc/en/articles/serial-uart/>`_ (written for + FreeBSD, but contains a large amount of general information). diff --git a/docs/source/usb.rst b/docs/source/usb.rst new file mode 100644 index 0000000..80c40ca --- /dev/null +++ b/docs/source/usb.rst @@ -0,0 +1,49 @@ +.. highlight:: cpp + +.. _usb: + +USB +=== + +The STM32 microprocessors include a dedicated USB peripheral which can +be configured to act as a general USB slave device with transfer rates +up to 12Mbps. (It unfortunately can't be configured as a host or +on-the-go device). By default, the peripheral is configured for two +uses: first, to receive sketch/program uploads from the :ref:`IDE +<ide>`, and second, to emulate a regular serial port for use as a +terminal (text read/write). + +The emulated terminal is relatively slow and inefficient; it is best +for transferring data at regular serial speeds (kilobaud). Library +support for accessing the emulated terminal is available at the +:ref:`SerialUSB <lang-serialusb>` reference. + +The SerialUSB channel is used with the :ref:`Maple bootloader +<bootloader>` to reprogram the board: a :ref:`magic sequence of +control line toggles and transmitted data <bootloader-rev3>` causes a +Maple to reset itself and enter bootloader mode. As an unfortunate +consequence, the auto-reset will not work if the IDE can not access +the serial port, either due to a conflict with another program (serial +monitor) or because the interface has been disabled from the Maple +side (through :ref:`SerialUSB.end() <lang-serialusb-end>`). A +solution to the second problem is the use of :ref:`perpetual +bootloader mode <troubleshooting-perpetual-bootloader>`. + +Recommended Reading +------------------- + +* `USB in a Nutshell <http://www.beyondlogic.org/usbnutshell/usb1.shtml>`_, an overview from Beyond Logic +* `USB made simple <http://www.usbmadesimple.co.uk/>`_, an illustrated series of articles on USB +* The `USB 2.0 Specification <http://www.usb.org/developers/docs/>`_ (`direct link <http://www.usb.org/developers/docs/usb_20_070113.zip>`_) +* `Embedded USB - a brief tutorial <http://www.computer-solutions.co.uk/info/Embedded_tutorials/usb_tutorial.htm>`_ +* `Wikipedia article on Universal Serial Bus (USB) <http://en.wikipedia.org/wiki/Universal_Serial_Bus>`_ +* Linux Kernel documentation for `USB ACM <http://www.kernel.org/doc/Documentation/usb/acm.txt>`_ and `USB Serial <http://www.kernel.org/doc/Documentation/usb/usb-serial.txt>`_ +* `USB Glossary of Terms <http://belcarra.com/usb_glossary.html>`_ +* ST documentation: + * Reference Manual `RM0008 + <http://www.st.com/web/en/resource/technical/document/reference_manual/CD00171190.pdf>`_ + (PDF), Chapter 23, "Universal serial bus full-speed device + interface" + * Programming Manual `PM0056 + <http://www.st.com/st-web-ui/static/active/en/resource/technical/document/programming_manual/CD00228163.pdf>`_ + (PDF; assembly language and register reference) diff --git a/docs/source/whats-new.rst b/docs/source/whats-new.rst new file mode 100644 index 0000000..c7d10c5 --- /dev/null +++ b/docs/source/whats-new.rst @@ -0,0 +1,81 @@ +.. highlight:: c + +What's New +========== + +.. FIXME [RELEASE] finish. + +This page tracks updates to libmaple and MapleIDE. + +.. contents:: + :local: + :depth: 1 + +v0.0.13 +------- + +.. We started doing this as we updated the docs on 29 Jun 2012, so +.. updates before then need to be pulled from libmaple's Git logs. + +**General Changes** + +- Additional STM32 support: for this release, libmaple was taught + how to target STM32F1 value line (thanks to Anton Eltchaninov) and + STM32F2 series microcontrollers. It learned a huge bag of new + tricks as a result, so this list is only a summary of the most + important changes. + +- New include style: You should now include libmaple and Wirish + headers like this (respectively):: + + #include <libmaple/libmaple.h> + #include <wirish/wirish.h> + + The old include style (e.g. ``#include "libmaple.h"``) is now + **deprecated**, and will **break in the next release**. This is more + standard usage for libraries, and was necessary to e.g. allow for + implementing a Wiring/Arduino-style SPI library (which is included + as ``#include "SPI.h"`` and clashes with :ref:`libmaple-spi` on + case-insensitive filesystems like OS X's). + +- :ref:`Windows instructions <toolchain-win-setup>` for the + :ref:`unix-toolchain`. + +**Wirish** + +- Wire I2C library: New, improved, and more Arduino-compatible + :ref:`Wire <libs-wire>` library, thanks to Trystan Jones. + +**libmaple proper** + +Better documentation: The old documentation for libmaple's C layer did +little more than list the Doxygen comments in the source code. It now +includes explanatory material and usage notes. See +:ref:`libmaple-apis`. + +.. FIXME [0.0.13] this is ugly + +Major changes by header follow. + +.. list-table:: + :header-rows: 1 + :widths: 1 10 + + * - Header + - Changes + + * - :ref:`libmaple-rcc` + - :ref:`rcc_clk_init() <rcc-rcc_clk_init>` is deprecated. Use + :ref:`rcc_configure_pll() <libmaple-rcc-rcc_configure_pll>` as + the basis for a portable replacement; see the + ``rcc_clk_init()`` docs for a porting guide. + + * - :ref:`libmaple-libmaple_types` + - Various new attributes and type qualifiers. + + * - :ref:`libmaple-adc` + - New :ref:`adc_enable_single_swstart() + <adc-adc_enable_single_swstart>` and :ref:`adc_config_gpio() + <adc-adc_config_gpio>`, for portably enabling ADC peripherals + and their associated pins for use with :ref:`adc_read() + <adc-adc_read>`. |