diff options
Diffstat (limited to 'docs/source')
170 files changed, 12482 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/apilist.html b/docs/source/_static/apilist.html new file mode 100644 index 0000000..e9eb8e3 --- /dev/null +++ b/docs/source/_static/apilist.html @@ -0,0 +1,5 @@ +{# Filename: .static/apilist.html #} +{% set parents = parents.pop() %} +{% if parents %} +<a href="{{ parents.link|e }}">{{ parents.title }}</a> +{% endif %}
\ No newline at end of file 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/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/libmaple-screenshot-small.png b/docs/source/_static/img/libmaple-screenshot-small.png Binary files differnew file mode 100644 index 0000000..f2be783 --- /dev/null +++ b/docs/source/_static/img/libmaple-screenshot-small.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/_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/layout.html b/docs/source/_templates/layout.html new file mode 100644 index 0000000..93547f0 --- /dev/null +++ b/docs/source/_templates/layout.html @@ -0,0 +1,5 @@ +{% extends "!layout.html" %} +{% block rootrellink %} + <li><a href="http://leaflabs.com/">LeafLabs</a> |</li> + {{ super() }} +{% endblock %} diff --git a/docs/source/adc.rst b/docs/source/adc.rst new file mode 100644 index 0000000..6bbbac2 --- /dev/null +++ b/docs/source/adc.rst @@ -0,0 +1,81 @@ +.. _adc: + +===== + ADC +===== + +Analog-Digital Conversion is the process of reading a physical voltage +as a number. The Maple has a large number of pins which are capable of +taking 12-bit ADC measurements, which means that voltages from ground +to +3.3v are read as numbers from 0 to 4095; this corresponds to a +theoretical sensitivity of just under 1 millivolt. In reality, a +number of factors introduce noise and bias into this reading and a +number of techniques must be used to get good precision and accuracy. + +.. compound:: + + The header pins with ADC functionality (marked as "AIN" on the + silkscreen) are: + + D0, D1, D2, D3, D10, D11, D12, D13, D15, D16, D17, D18, D19, D20, D27, D28 + + Note that pins 3, 27, and 28 are not marked AIN on the silkscreen + for Maple revisions through Rev 5, however, they **do work** as + analog input pins. + +.. contents:: Contents + :local: + +.. _adc-noise-bias: + +Noise and Bias +-------------- + +The biggest issues with analog-digital conversion are noise and bias. +With the Maple, we have tried to isolate the ADC pins and traces from +strong noise sources but there are always trade--offs between noise, +additional functionality, cost, and package size. + +The 6 ADC pins in a bank (D15--D20) generally have the least +noise and should be used for fine measurements. If the 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. + +An important factor when taking a voltage reading is the reference +voltages that the sample is being compared against. In the case of the +Maple, the high reference is |vcc| and the low reference is ground. +This means that noise or fluctuations on either |vcc| or ground will +affect the measurement. It also means that the voltage you are trying +to sample must be between ground and 3.3V. In the case of a variable +reading, it is best if the voltage varies over the entire range of +0--3.3V; otherwise, only a fraction of the sensitivity is being +leveraged. Resistor dividers and constant voltage diodes are basic +tools which can help bring a given voltage signal into the appropriate +range; opamps and other powered components can also be used. + +.. _adc-function-reference: + +Function Reference +------------------ + +.. doxygenfunction:: analogRead + +.. doxygenfunction:: pinMode + +.. doxygenenum:: WiringPinMode + +.. _adc-recommended-reading: + +Recommended Reading +------------------- + +* `Wikipedia article on Analog-to-digital converter <http://en.wikipedia.org/wiki/Analog-to-digital_converter>`_ +* `Arduino Analog Input Tutorial <http://arduino.cc/en/Tutorial/AnalogInputPins>`_ +* STMicro documentation for STM32F103RB microcontroller: + + * `All <http://www.st.com/mcu/devicedocs-STM32F103RB-110.html>`_ + * `Datasheet <http://www.st.com/stonline/products/literature/ds/13587.pdf>`_ (pdf) + * `Reference Manual <http://www.st.com/stonline/products/literature/rm/13902.pdf>`_ (pdf) + * `Application Note on ADC Modes (pdf) <http://www.st.com/stonline/products/literature/an/16840.pdf>`_ + * `Application Note on ADC Oversampling (pdf) <http://www.st.com/stonline/products/literature/an/14183.pdf>`_ diff --git a/docs/source/arm-gcc.rst b/docs/source/arm-gcc.rst new file mode 100644 index 0000000..ef745f5 --- /dev/null +++ b/docs/source/arm-gcc.rst @@ -0,0 +1,70 @@ + +.. _arm-gcc: + +GCC for Maple +============= + +This document provides notes on the current usage of +``arm-none-eabi-gcc``, the `CodeSourcery <http://codesourcery.com>`_ +version of the GNU `GCC <http://gcc.gnu.org/>`_ compilers used to +compile programs for the Maple. It is not intended as a reference +manual for GCC; such manuals are available `elsewhere +<http://gcc.gnu.org/>`_. + +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`` in concert with a standard +Unix toolchain are referred to our :ref:`unix-toolchain` reference, +which describes how to set up such an environment. + +LeafLabs mirrors some of the more recent versions of the compiler +under http://static.leaflabs.com/pub/codesourcery/\ , including +versions for OS X, win32, and 32-bit Linux. + +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 +:ref:`libmaple <unix-toolchain>`. The information in this section is +subject to change without notice. + +.. 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 + +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-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``: You can direct the linker script provided + with libmaple to store a variable in flash by using + ``__attribute__((section (".USER_FLASH")))``, like so:: + + uint32 arr[] __attribute__((section (".USER_FLASH"))) = {...}; + diff --git a/docs/source/bootloader.rst b/docs/source/bootloader.rst new file mode 100644 index 0000000..57833ed --- /dev/null +++ b/docs/source/bootloader.rst @@ -0,0 +1,682 @@ +.. highlight:: sh + +===================== + Maple Bootloader(s) +===================== + +.. TODO: add a section on flashing your own bootloader + +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**: http://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 +<http://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, 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 some 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 that +happens automatically when you compile (``setupUSB()`` is appended to +``setup()``). This user mode code only implements a CDC ACM class USB +device, giving you functions like ``Usb.print()``. Separating these +two modes fixed the driver issue, required no complicated compound USB +device nonsense, 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 have +to reset the board, then initiate a DFU transaction. This reset is +performed automatically by the IDE by sending a command over the USB +serial port. You can generate this reset on your own using a Python +script or some other scheme. All you need do is: + +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 its +the reason the bootloader on Maple Rev3 stays alive for so +long. Sometimes the bootloader was exiting before the OS had even +enumerated the device! Once in bootloader mode, however, +: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. + +.. .. _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 +---------------------------- + +The STM32 microprocessor on the Maple comes with a built-in hardware +bootloader that can be used to flash a new (software) bootloader onto +the chip. This section describes how to go about this, using a Maple +Rev 3 or higher (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>`_). + +.. warning:: This section is directed at users wishing to write a + custom bootloader for the Maple, or update their bootloader to a + more recent version. It's generally not necessary to do so, and it + is possible to make a mistake and e.g. render your Maple unable to + communicate with the IDE. Know what you're doing, and proceed with + caution. + +.. highlight:: sh + +Setup +^^^^^ + +In order to follow these instructions, you will need: + +- A binary of the bootloader you want to upload +- Hardware for communicating between the Maple and your computer over + serial. +- `Python <http://python.org>`_ version 2.5 or higher, with the + `PySerial <http://pyserial.sourceforge.net/>`_ library installed. + +**Step 1: Obtain a bootloader binary**. The first thing you'll need to +do is to compile your bootloader binary. Note that an ASCII +representation of the binary, such as the Intel .hex format, will not +suffice. For example, you can run (on a :ref:`suitably configured +system <unix-toolchain>`) the following to obtain a binary of the +bootloader currently used on the Maple:: + + $ git checkout git://github.com/leaflabs/maple-bootloader.git + $ cd maple-bootloader + $ make + $ ls -lh build/maple-boot.bin # this is the compiled bootloader binary + +**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 (pin 8), FTDI RX to ``Serial1`` TX (pin 7), FTDI ground to +Maple's GND, and its 3.3V pin to Maple's Vin (use the Maple's +silkscreen for help locating these pins). At this point, you're ready +to plug the FTDI board into your computer (via USB). + +The ``Serial1`` pins are documented :ref:`here <lang-serial>`. + +**Step 3: Put your Maple into serial bootloader mode**. Do this by +pressing the RESET button, then *while RESET is held down*, pressing +and holding the BUT button. Next, *making sure to keep BUT held +down*, release the RESET button and wait for a few seconds before +releasing BUT. + +**Step 4: Obtain stm32loader.py**. The +script ``stm32loader.py`` is provided with libmaple. If you have set +up the :ref:`Unix toolchain <unix-toolchain>`, it is available in +libmaple/support/stm32loader.py. Otherwise, you can download it +directly from `github +<https://github.com/leaflabs/libmaple/raw/master/support/stm32loader.py>`_ +(click the link, then save the file somewhere on your system). + +Flashing the new Bootloader +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +We'll use ``new-boot.bin``, ``ser-port``, and ``stm32loader.py`` to +respectively refer to the absolute paths to the bootloader binary +(from Step 1), the serial port device file or COMM port (from Steps 2 +and 3), and the stm32loader.py script. + +.. highlight:: sh + +You can run :: + + $ python stm32loader.py -h + +to obtain usage information. The incantation for uploading a +bootloader binary ``new-bootloader.bin`` is :: + + $ python stm32loader.py -p ser-port -evw new-boot.bin + +If all goes well, you'll see a bunch of output, then "Verification +OK". If something goes wrong, the `forum`_ is probably your best bet +for obtaining help, with IRC (irc.freenode.net, #leafblowers) being +another option. If all else fails, you can always `contact us +directly`_! diff --git a/docs/source/compatibility.rst b/docs/source/compatibility.rst new file mode 100644 index 0000000..848a3d3 --- /dev/null +++ b/docs/source/compatibility.rst @@ -0,0 +1,266 @@ +.. highlight:: cpp + +.. _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 (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 +:command:`avr-gcc` 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 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, which in +the worst case would quadruple program size. In reality, the 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 +-------------------------------------- + +The numbering of headers is different; on the Maple each GPIO has a +unique number: D0, D1, D2, all the way up to D37 (actually, there are +:ref:`a few more <jtag>`...). On the Arduino, the analog pins are +numbered separately (A0-A5) from the digital pins (D0\ -D13). + +The incompatible hardware differences are: + +* **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. We did our best! It may be possible to reroute this + peripheral internally using low level configuration, but we haven't + looked in to it. + +* **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 (14) 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 and Analog Input pins can + be configured as ``INPUT_ANALOG`` and ``PWM`` respectively. 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 +------------------------------- + +.. 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/mcu/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. (Patches are welcome!) + +- 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/conf.py b/docs/source/conf.py new file mode 100644 index 0000000..1ad4e57 --- /dev/null +++ b/docs/source/conf.py @@ -0,0 +1,273 @@ +# -*- 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 + + +# 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 libmaple/docs/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', '_static'] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The encoding of source files. +#source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'Maple' +copyright = u'2010, 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. +release = '0.0.9' + +# 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' : 'Lucidia' +} + +# 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 + ' Documentation' + +# 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. +# re-add commented line when custom template for api finished +html_sidebars = { + '**': ['globaltoc.html', 'searchbox.html'], + #'lang/api**':['searchbox.html', 'apilist.html'], +} + + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# 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 ------------------------------------------ + +breathe_projects = {'libmaple' : os.path.join(os.environ['LIB_MAPLE_HOME'], + 'docs', 'doxygen', 'xml')} + +breathe_default_project = 'libmaple' diff --git a/docs/source/epilog.rst b/docs/source/epilog.rst new file mode 100644 index 0000000..e64103c --- /dev/null +++ b/docs/source/epilog.rst @@ -0,0 +1,8 @@ +.. 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/ diff --git a/docs/source/errata.rst b/docs/source/errata.rst new file mode 100644 index 0000000..8feb6ea --- /dev/null +++ b/docs/source/errata.rst @@ -0,0 +1,140 @@ +.. _errata: + +======== + Errata +======== + +This page is a collection of known issues and warnings for each +revision of the Maple board. The failure modes aren't design errors, +but are easy ways to break or damage your board permanently. For a +list of differences between the Maple and Arduinos, see the +:ref:`compatibility reference <compatibility>`. + +The errata are grouped by Maple version ("Rev"). Rev 5 is currently +on sale. If you are unsure which version you own, the :ref:`Maple +hardware page <maple-hardware-identify-rev>` has pictures and +descriptions of each version. + +.. contents:: Contents + :local: + +Maple Rev 5 +----------- + +Known issues: + +* **Pin 3 AIN missing**: Pin 3 is capable of analog input, but the + corresponding "AIN" is missing from its silkscreen. + +* **GPIO 39-43 not configured**: this is really more of a software + "TODO" item. Some of the JTAG header pins are numbered 39-43. These + STM32 pins are indeed fully functional :ref:`GPIO <gpio>` when the a + :ref:`JTAG <jtag>` device is not connected, but we have not enabled + them in software and thus they can not be accessed with the regular + :ref:`lang-pinmode` or :ref:`lang-digitalwrite` functions. + +Potential failure modes: + +* **TTL voltage on non-tolerant pins**: not all header pins are 5V + compatible; connecting certain serial devices in the wrong way could + over voltage the pins. The :ref:`Pin-Mapping Mega Table + <pin-mapping-mega-table>` details which pins are 5V-tolerant. + +Maple Rev 3 +----------- + +Known issues: + +* **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 (really?), 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. + +* **GPIO 39-43 not configured**: this is really more of a software + "TODO" item. Some of the JTAG header pins are numbered 39-43. These + STM32 pins are indeed fully functional :ref:`GPIO <gpio>` when the a + :ref:`JTAG <jtag>` device is not connected, but we have not enabled + them in software and thus they can not be accessed with the regular + :ref:`lang-pinmode` or :ref:`lang-digitalwrite` functions. + +* **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. + +* **PWM Marketing Mistake**: We originally sold the Maple advertising + 22 channels of 16-bit hardware PWM; actually the Maple only has 15. + +Potential failure modes: + +* **TTL voltage on non-tolerant pins**: not all header pins are 5V + compatible; connecting certain serial devices in the wrong way could + over voltage the pins. The :ref:`Pin-Mapping Mega Table + <pin-mapping-mega-table>` details which pins are 5V-tolerant. + +Maple Rev 1 +----------- + +Known issues: + +* **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 + geometrically isolated ADC V\ :sub:`ref` plane. + +* **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>`_. + +* **PWM Marketing Mistake**: We originally sold the Maple advertising + 22 channels of 16-bit hardware PWM; actually the Maple only has 15. + +Potential failure modes: + +* **TTL voltage on non-tolerant pins**: not all header pins are 5v + compatible; connecting certain serial devices in the wrong way could + over voltage the pins. The :ref:`Pin-Mapping Mega Table + <pin-mapping-mega-table>` details which pins are 5V-tolerant. diff --git a/docs/source/external-interrupts.rst b/docs/source/external-interrupts.rst new file mode 100644 index 0000000..b2cbbb1 --- /dev/null +++ b/docs/source/external-interrupts.rst @@ -0,0 +1,119 @@ +.. highlight:: cpp + +.. _external-interrupts: + +External Interrupts +=================== + +External interrupts can be used to trigger routines to run in response +to changes in voltage on a pin. Each GPIO pin on the Maple can be used +to detect transitions such as when the voltage goes from low to high, +or from high to low. This technique can be used to avoid unnecessary +polling of the state of a pin. + +.. _contents: Contents + :local: + + +Overview +-------- + +External interrupts are often used to detect when events happen +outside of the microcontroller. These can be used to tell the Maple +when events happen, such as 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 can react to it with a preset +*interrupt handler*. + +Every GPIO pin on the Maple can be used as an external interrupt, +subject to certain constraints; there can be a maximum of 16 different +external interrupts set up at a time on the Maple. This is because the +external interrupt lines on the STM32 are multiplexed between GPIO +ports. In effect, this means that every pin on the Maple maps to a +certain EXTI line, and within that EXTI line, only one of the pins +that maps to it can be used as an external interrupt at a time. + +The following table shows which pins can be used on which lines. + +.. list-table:: + :widths: 1 1 + :header-rows: 1 + + * - EXTI Line + - Maple pins + * - EXTI0 + - 2, 15, 27 + * - EXTI1 + - 3, 16, 28 + * - EXTI2 + - 1, 17, 25 + * - EXTI3 + - 0, 18 + * - EXTI4 + - 10, 19 + * - EXTI5 + - 4, 13, 20 + * - EXTI6 + - 5, 12, 35 + * - EXTI7 + - 9, 11, 36 + * - EXTI8 + - 6, 14, 37 + * - EXTI9 + - 7, 25, 28 + * - EXTI10 + - 8, 26, 29 + * - EXTI11 + - 30 + * - EXTI12 + - 31 + * - EXTI13 + - 21, 32 + * - EXTI14 + - 22, 33 + * - EXTI15 + - 23, 34 + +.. note:: + + You should set the :ref:`pin mode <lang-pinmode>` of your + desired pin to an input mode (e.g ``INPUT`` or ``INPUT_FLOATING``, + ``INPUT_PULLUP``, ``INPUT_PULLDOWN``). + + +Function Reference +------------------ + +- :ref:`attachInterrupt() <lang-attachinterrupt>` +- :ref:`detachInterrupt() <lang-detachinterrupt>` + +Code example +------------ + +Blink the LED on every transition:: + + int pin = 13; + volatile int state = LOW; + + void setup() { + pinMode(pin, OUTPUT); + pinMode(0, INPUT_FLOATING); + attachInterrupt(0, blink, CHANGE); + } + + void loop() { + digitalWrite(pin, state); + } + + void blink() { + state = !state; + } + + +Recommended Reading +------------------- + +* STMicro documentation for STM32F103RB microcontroller: + + * `Datasheet <http://www.st.com/stonline/products/literature/ds/13587.pdf>`_ (pdf) + * `Reference Manual <http://www.st.com/stonline/products/literature/rm/13902.pdf>`_ (pdf) diff --git a/docs/source/gpio.rst b/docs/source/gpio.rst new file mode 100644 index 0000000..4017862 --- /dev/null +++ b/docs/source/gpio.rst @@ -0,0 +1,102 @@ +.. _gpio: + +GPIO +==== + +The Maple features 38 ready-to-use general purpose input/output (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. + +Many of these pins may additionally be used for special features or +peripheral functions. This page documents those capabilities, by pin. + +The current and voltage limitations have not been copied over from the +STM32 datasheet (see the :ref:`Recommended Reading +<gpio-recommended-reading>` for a link). In particular, a number of +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), while some are not. + +.. contents:: Contents + :local: + +.. _pin-mapping-mega-table: + +Pin Mapping Mega Table +---------------------- + +This table shows the available functionality on every GPIO pin, by +peripheral type. The "STM32" column refers to the port and number that +the header is connected to on the microcontroller. The "5V?" column +documents whether or not the pin is 5 volt tolerant (see above). + +.. csv-table:: + :header: "Pin", "STM32", ":ref:`ADC <adc>`", ":ref:`Timer <timers>`", ":ref:`I2C <i2c>`", ":ref:`UART <usart>`", ":ref:`SPI <spi>`", "5v?" + + "D0", "PA3", "ADC3", "TIM2_CH4", "-", "USART2_RX", "-", "No" + "D1", "PA2", "ADC2", "TIM2_CH3", "-", "USART2_TX", "-", "No" + "D2", "PA0", "ADC0", "TIM2_CH1_ETR", "-", "USART2_CTS", "-", "No" + "D3", "PA1", "ADC1", "TIM2_CH2", "-", "USART2_RTS", "-", "No" + "D4", "PB5", "-", "-", "ISC1_SMBA", "-", "-", "No" + "D5", "PB6", "-", "TIM4_CH1", "I2C1_SCL", "-", "-", "Yes" + "D6", "PA8", "-", "TIM1_CH1", "-", "USART1_CK", "-", "Yes" + "D7", "PA9", "-", "TIM1_CH2", "-", "USART1_TX", "-", "Yes" + "D8", "PA10", "-", "TIM1_CH3", "-", "USART1_RX", "-", "Yes" + "D9", "PB7", "-", "TIM4_CH2", "I2C1_SDA", "-", "-", "Yes" + "D10", "PA4", "ADC4", "-", "-", "USART2_CK", "SPI1_NSS", "No" + "D11", "PA7", "ADC7", "TIM3_CH2", "-", "-", "SPI1_MOSI", "No" + "D12", "PA6", "ADC6", "TIM3_CH1", "-", "-", "SPI1_MISO", "No" + "D13", "PA5", "ADC5", "-", "-", "-", "SPI1_SCK", "No" + "D14", "PB8", "-", "TIM4_CH3", "-", "-", "-", "Yes" + "D15", "PC0", "ADC10", "-", "-", "-", "-", "No" + "D16", "PC1", "ADC11", "-", "-", "-", "-", "No" + "D17", "PC2", "ADC12", "-", "-", "-", "-", "No" + "D18", "PC3", "ADC13", "-", "-", "-", "-", "No" + "D19", "PC4", "ADC14", "-", "-", "-", "-", "No" + "D20", "PC5", "ADC15", "-", "-", "-", "-", "No" + "D21", "PC13", "-", "-", "-", "-", "-", "No" + "D22", "PC14", "-", "-", "-", "-", "-", "No" + "D23", "PC15", "-", "-", "-", "-", "-", "No" + "D24", "PB9", "-", "TIM4_CH4", "-", "-", "-", "Yes" + "D25", "PD2", "-", "TIM3_ETR", "-", "-", "-", "Yes" + "D26", "PC10", "-", "-", "-", "-", "-", "Yes" + "D27", "PB0", "ADC8", "TIM3_CH3", "-", "-", "-", "No" + "D28", "PB1", "ADC9", "TIM3_CH4", "-", "-", "-", "No" + "D29", "PB10", "-", "-", "I2C2_SCL", "USART3_TX", "-", "Yes" + "D30", "PB11", "-", "-", "I2C2_SDA", "USART3_RX", "-", "Yes" + "D31", "PB12", "-", "TIM1_BKIN", "I2C2_SMBAL", "USART3_CK", "SPI2_NSS", "Yes" + "D32", "PB13", "-", "TIM1_CH1N", "-", "USART3_CTS", "SPI2_SCK", "Yes" + "D33", "PB14", "-", "TIM1_CH2N", "-", "USART3_RTS", "SPI2_MISO", "Yes" + "D34", "PB15", "-", "TIM1_CH3N", "-", "-", "SPI2_MOSI", "Yes" + "D35", "PC6", "-", "-", "-", "-", "-", "Yes" + "D36", "PC7", "-", "-", "-", "-", "-", "Yes" + "D37", "PC8", "-", "-", "-", "-", "-", "Yes" + +.. _gpio-modes: + +GPIO Modes +---------- + +.. doxygenenum:: WiringPinMode + +Function Reference +------------------ + +.. doxygenfunction:: pinMode + +.. doxygenfunction:: digitalRead + +.. doxygenfunction:: digitalWrite + +.. doxygenfunction:: analogRead + +.. _gpio-recommended-reading: + +Recommended Reading +------------------- + +STMicro documentation for STM32F103RB microcontroller: + + * `Datasheet <http://www.st.com/stonline/products/literature/ds/13587.pdf>`_ (pdf) + * `Reference Manual <http://www.st.com/stonline/products/literature/rm/13902.pdf>`_ (pdf) diff --git a/docs/source/hardware/maple-mini.rst b/docs/source/hardware/maple-mini.rst new file mode 100644 index 0000000..a8a4186 --- /dev/null +++ b/docs/source/hardware/maple-mini.rst @@ -0,0 +1,6 @@ +.. _hardware-maple-mini: + +Maple Mini +========== + +Stub. 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.rst b/docs/source/hardware/maple.rst new file mode 100644 index 0000000..8350cc5 --- /dev/null +++ b/docs/source/hardware/maple.rst @@ -0,0 +1,104 @@ +.. highlight:: sh + +.. _hardware-maple: + +Maple +===== + +.. contents:: Contents + :local: + +.. _maple-hardware-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. Known issues are listed in the :ref:`errata <errata>`. + +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 + +.. rubric:: Footnotes + +.. [#frev2_4] Revs 2 and 4 were prototypes that didn't pass internal + testing. + +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. +It also includes a built-in LiPo battery charger. + +.. figure:: /_static/img/maple_rev3.png + :align: center + :alt: Maple Rev 3 + +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 + +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. However, don't do this while simultaneously powering the +Maple from another source, or you could damage the 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 also light up. + +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 + diff --git a/docs/source/i2c.rst b/docs/source/i2c.rst new file mode 100644 index 0000000..b4a996b --- /dev/null +++ b/docs/source/i2c.rst @@ -0,0 +1,87 @@ +.. _i2c: + +===== +|i2c| +===== + +.. note:: + + The |i2c| interface is currently only available from the 'i2c' branch + of the github `libmaple <http://github.com/leaflabs/libmaple>`_ + repository. + +|i2c| is a crude and easy-to-hack serial protocol that requires only +two wires/channels for communication between many devices. Every +message passed on the bus is between a *master* (who initiates the +message) and a *slave* device. Slaves are addressed using 7-bit +addresses (up to 127 unique devices); 10-bit addressing is possible, +but currently unimplemented. 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. The 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. + +.. contents:: Contents + :local: + +Hardware/Circuit Design +----------------------- + +The Maple has two |i2c| ports. Port 1 (i2c1) has SDA on header D9 and +SCL on D5; Port 2 (i2c2) has SDA on D30 and SCL on D29. + +The Maple reliably communicates 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 +------------------ + +The function API for |i2c| is not finished! See the `source code +<http://github.com/leaflabs/libmaple/blob/i2c/libmaple/i2c.h>`_ for +now. + +.. TODO link to libmaple I2C docs once (1) finished, (2) in master + +SMBus +----- + +The STM32 microcontroller has hardware support for SMBus; we simply +have not written software for it. The SMBAL line for i2c1 is on header +D4 and for i2c2 is on D31. + +.. TODO link to libmaple SMBus docs once (1) finished, (2) in master + +.. _i2c-recommended-reading: + +Recommended Reading +------------------- + +* `i2c-bus.org <http://www.i2c-bus.org/>`_ +* `Wikipedia Article on i2c <http://en.wikipedia.org/wiki/I%C2%B2C>`_ +* `Arduino i2c/TWI reference <http://www.arduino.cc/playground/Learning/I2C>`_ +* STMicro documentation for STM32F103RB microcontroller: + + * `Datasheet <http://www.st.com/stonline/products/literature/ds/13587.pdf>`_ (pdf) + * `Reference Manual <http://www.st.com/stonline/products/literature/rm/13902.pdf>`_ (pdf) + * `Application Note on Advanced I2C Usage + <http://www.st.com/stonline/products/literature/an/15021.pdf>`_ + (pdf) diff --git a/docs/source/ide.rst b/docs/source/ide.rst new file mode 100644 index 0000000..b3ef653 --- /dev/null +++ b/docs/source/ide.rst @@ -0,0 +1,136 @@ +.. _ide: + +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. + +The :ref:`Maple Quickstart <maple-quickstart>` is another good source of +information on the IDE; it is especially useful for setting up a +computer for the first time. + +.. figure:: /_static/img/ide-blinky.png + :align: center + :alt: Maple IDE + +.. _ide-verify: + +Verify +------ + +.. image:: /_static/img/button-verify.png + :align: left + +Click Verify to compile the current sketch. + +.. _ide-stop: + +Stop +---- + +.. image:: /_static/img/button-stop.png + :align: left + +Click Stop to cancel a compilation. + +.. _ide-new: + +New +--- + +.. image:: /_static/img/button-new.png + :align: left + +Click New to begin a fresh sketch. + +.. _ide-open: + +Open +---- + +.. image:: /_static/img/button-open.png + :align: left + +Click Open to open a new sketch. By default, this will look in you +*sketchbook*, which is a directory on your system which contains all +of your sketches. The default directory of your sketchbook varies by +operating system; you can change it in the IDE preferences. + +.. _ide-save: + +Save +---- + +.. image:: /_static/img/button-save.png + :align: left + +Click Save to save the currently opened sketch. + +.. _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 Serial-over-USB connection the Maple has +established 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 click Upload without having made these choices; The IDE +*should* prompt you to do so. However, if you're trying to upload and +are unsuccessful, make sure you've made choices for both board and +serial port. + +For more help, the upload process is documented in more detail (with +screenshots) 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. + +In any case, you can always find us on the `forum`_ or `contact us +directly`_. + +.. _ide-serial-monitor: + +Serial Monitor +-------------- + +.. image:: /_static/img/button-serial-monitor.png + :align: left + +Click Serial Monitor to open up a communications channel between your +PC and the Maple's :ref:`Serial-over-USB <lang-serialusb>` +(``SerialUSB``) virtual serial port. + +If the serial monitor is open, any information sent to the computer +(e.g. using :ref:`SerialUSB.println() <lang-serialusb-println>` will +be displayed in the large text area. You can send data to the Maple +(to be read with e.g. :ref:`SerialUSB.read() <lang-serialusb-read>`) +by typing into the small text box and either hitting the Enter key or +pressing the Send button. + +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. diff --git a/docs/source/index.rst b/docs/source/index.rst new file mode 100644 index 0000000..5c1718f --- /dev/null +++ b/docs/source/index.rst @@ -0,0 +1,86 @@ +.. _index: + +Maple Documentation Contents +============================ + +Welcome! This is the Maple documentation index. If you just bought a +Maple, you probably want to head to the :ref:`quickstart +<maple-quickstart>`. If you're having problems, check out the +:ref:`troubleshooting <troubleshooting>` and :ref:`known problems +<errata>` pages. + +Have fun! + +.. _index-usage: + +**Usage Guides:** + +.. toctree:: + :maxdepth: 1 + + Quickstart <maple-quickstart> + IDE Installation <maple-ide-install> + IDE Usage <ide> + Command-Line Toolchain <unix-toolchain> + +.. _index-maple-programming: + +**Maple Programming:** + +.. toctree:: + :maxdepth: 1 + + Language <language> + Libraries <libraries> + Arduino Compatibility <compatibility> + libmaple <libmaple> + External Interrupts <external-interrupts> + Bootloader <bootloader> + Troubleshooting <troubleshooting> + Known Problems <errata> + +.. _index-hardware: + +**Hardware Peripherals:** + +.. toctree:: + :maxdepth: 1 + + adc + gpio + i2c + jtag + pwm + spi + timers + usb + usart + +.. _index-schematics: + +**Board Hardware Documentation:** + +.. toctree:: + :maxdepth: 1 + + hardware/maple.rst + +.. TODO write/include these upon Mini and Native release + +.. toctree:: + :hidden: + + hardware/maple-mini.rst + hardware/maple-native.rst + +.. _index-reference: + +**Reference:** + +.. toctree:: + :maxdepth: 1 + + Technical Specifications <specs> + Complete Language Index <language-index> + + diff --git a/docs/source/jtag.rst b/docs/source/jtag.rst new file mode 100644 index 0000000..e3c8111 --- /dev/null +++ b/docs/source/jtag.rst @@ -0,0 +1,65 @@ +.. _jtag: + +====== + JTAG +====== + +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 that the +:ref:`ASSERT <language-assert>` framework 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 + + JTAG wiring diagram (`large version + <http://leaflabs.com/wp-content/uploads/2010/11/maple-jtagadapter.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 by default. If you know ahead of time that you'll be +needing it, and you order `straight from LeafLabs +<http://leaflabs.com/store/>`_, add a comment to your order and we can +probably solder one on for no charge. Otherwise, you can simply +attach standard 0.1" pitch male header pins (either the exact 4x2 +block or two 4-pin pieces of breakaway straight header). For a one-off +usage hack, the header can be jammed in the holes and twisted to +ensure electrical contact. + +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 euro plus shipping (as of November 2010). + +Recommended Reading +------------------- + +* `Wikipedia Article on Joint Test Action Group (JTAG) <http://en.wikipedia.org/wiki/Joint_Test_Action_Group>`_ +* `STM32/gdb/OpenOCD HOWTO <http://fun-tech.se/stm32/OpenOCD/gdb.php>`_ +* STMicro documentation for STM32F103RB microcontroller: + + * `Datasheet <http://www.st.com/stonline/products/literature/ds/13587.pdf>`_ (pdf) + * `Reference Manual <http://www.st.com/stonline/products/literature/rm/13902.pdf>`_ (pdf) +* There's a `thread on JTAG + <http://forums.leaflabs.com/topic.php?id=536>`_ in our `forum`_ + which you may find useful. diff --git a/docs/source/lang/api/abs.rst b/docs/source/lang/api/abs.rst new file mode 100644 index 0000000..0cc6c23 --- /dev/null +++ b/docs/source/lang/api/abs.rst @@ -0,0 +1,49 @@ +.. 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:: 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..35c6fbc --- /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 board +contains a 16-channel, 12-bit analog to digital converter. This means +that it will map input voltages between 0 and 3.3 volts into integer +values between 0 and 4095. This yields a resolution between readings +of 3.3V / 4096 units, or 0.8 millivolts. 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. +Header pins on the Maple with ADC functionality (marked as "AIN" on +the silkscreen) are: + + 0, 1, 2, 3, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20, 27, 28 + +Note that pins 3, 27, and 28 are not marked AIN on the silkscreen +for Maple revisions through Rev 5, however, they **do work** as +analog input pins. + +Note +---- + +If the analog input pin is not connected to anything, the value +returned by analogRead() will fluctuate based on a number of factors +(e.g. the values of the other analog inputs, how close your hand is to +the board, etc.) in a seemingly random way. + + +Example +------- + + :: + + + int analogPin = 3; // potentiometer wiper (middle terminal) connected + // to analog pin 3. outside leads to ground and +3.3V + int val = 0; // variable to store the value read + + void setup() { + pinMode(analogPin, INPUT_ANALOG); // set up pin for analog input + SerialUSB.begin(); // set up usb virtual COM port + } + + 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; + +On the Arduino, the input range and resolution can be changed using +their implementation of `analogReference() +<http://arduino.cc/en/Reference/AnalogReference>`_\ . Because of the +way its hardware (as of Rev 5) was designed, it's not possible to +implement analogReference on the Maple, so this function doesn't +exist. 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. +Some basic tools to accomplish this are `resistor dividers +<http://en.wikipedia.org/wiki/Voltage_divider>`_ and `Zener diodes +<http://en.wikipedia.org/wiki/Voltage_source#Zener_voltage_source>`_\ +. However, opamps and other powered components can also be used if +greater precision is required. + +See also +-------- + +- :ref:`ADC note <adc>` +- `(Arduino) Tutorial: Analog Input Pins <http://arduino.cc/en/Tutorial/AnalogInputPins>`_ + +.. include:: 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..9147b96 --- /dev/null +++ b/docs/source/lang/api/analogwrite.rst @@ -0,0 +1,173 @@ +.. highlight:: cpp + +.. _lang-analogwrite: + +.. _lang-api-analogwrite: + + +analogWrite() +============= + +.. note:: + + On the Maple, calling analogWrite() is the same as calling + :ref:`lang-pwmwrite`\ ; we recommend using that function directly + instead. + + This is because PWM is not true analog output (i.e., is not the + output of a `DAC + <http://en.wikipedia.org/wiki/Digital-to-analog_converter>`_\ ), so + the function is badly named. For instance, analogWrite() **has + absolutely nothing to do with** :ref:`lang-analogread`\ , which is + potentially confusing. + + The alias of analogWrite() to pwmWrite() is provided 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,635, 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 the :ref:`pin mapping mega table +<pin-mapping-mega-table>` 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-attachinterrupt>` 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:`this table <pwm-timer-table>` is your + friend here). Let's say it's ``Timern``\ , where ``n`` is some + number 1, 2, 3, or 4. + +2. Call ``Timern.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-attachinterrupt>` and :ref:`PWM +<timers-pwm-conflicts>`\ . + +See also +-------- + +- :ref:`Maple PWM tutorial <pwm>` + +.. 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:: cc-attribution.txt diff --git a/docs/source/lang/api/attachinterrupt.rst b/docs/source/lang/api/attachinterrupt.rst new file mode 100644 index 0000000..7c5a6c7 --- /dev/null +++ b/docs/source/lang/api/attachinterrupt.rst @@ -0,0 +1,115 @@ +.. highlight:: cpp + +.. _lang-attachinterrupt: + +attachInterrupt() +================= + +Used to specify a function to call when an external interrupt (like an +GPIO changing from LOW to HIGH, a button getting pressed, etc.) +occurs. + +.. contents:: Contents + :local: + +Library Documentation +--------------------- + +.. FIXME 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 + +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 a few constraints you should be aware of if you're using +more than one interrupt at a time; the :ref:`external-interrupts` page +has the details. + +Using Interrupts +---------------- + +Interrupts are useful for making things happen automatically in +microcontroller programs, and can help solve timing problems. A +good task for using an interrupt might be reading a rotary encoder, +or monitoring user input. + +If you wanted to insure that a program always caught the pulses +from a rotary encoder, never missing a pulse, it would make it very +tricky to write a program to do anything else, because the program +would need to constantly poll the sensor lines for the encoder, in +order to catch pulses when they occurred. Other sensors have a +similar interface dynamic too, such as trying to read a sound +sensor that is trying to catch a click, or an infrared slot sensor +(photo-interrupter) trying to catch a coin drop. In all of these +situations, using an interrupt can free the microcontroller to get +some other work done while not missing the doorbell. + +Example +------- + +:: + + int maple_led_pin = 13; + volatile int state = LOW; // must declare volatile, since it's + // modified within the blink handler + + void setup() { + pinMode(maple_led_pin, OUTPUT); + attachInterrupt(0, blink, CHANGE); + } + + void loop() { + digitalWrite(maple_led_pin, state); + } + + void blink() { + state = !state; + } + +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:`detachInterrupt <lang-detachinterrupt>` +- :ref:`external-interrupts` + +.. include:: 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..dd5c050 --- /dev/null +++ b/docs/source/lang/api/bit.rst @@ -0,0 +1,44 @@ +.. _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:: 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..941f912 --- /dev/null +++ b/docs/source/lang/api/bitclear.rst @@ -0,0 +1,44 @@ +.. _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 +------- + +None. + + +Arduino Compatibility +--------------------- + +This implementation is compatible with that of Arduino. + + +See also +-------- + +- :ref:`bit <lang-bit>`\ () +- :ref:`bitRead <lang-bitread>`\ () +- :ref:`bitWrite <lang-bitwrite>`\ () +- :ref:`bitSet <lang-bitset>`\ () + + +.. include:: 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..46b4478 --- /dev/null +++ b/docs/source/lang/api/bitread.rst @@ -0,0 +1,46 @@ +.. _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:: 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..ccd76de --- /dev/null +++ b/docs/source/lang/api/bitset.rst @@ -0,0 +1,46 @@ +.. _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:: 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..b3feff2 --- /dev/null +++ b/docs/source/lang/api/bitwrite.rst @@ -0,0 +1,46 @@ +.. 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 version 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:: cc-attribution.txt diff --git a/docs/source/lang/api/cc-attribution.txt b/docs/source/lang/api/cc-attribution.txt new file mode 100644 index 0000000..e100140 --- /dev/null +++ b/docs/source/lang/api/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/api/constants.rst b/docs/source/lang/api/constants.rst new file mode 100644 index 0000000..72738b8 --- /dev/null +++ b/docs/source/lang/api/constants.rst @@ -0,0 +1,337 @@ +.. _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). + + +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. + +.. TODO? Following seems false; check it out sometime, leave out for now: + +.. A pin may also be configured as an ``INPUT`` with ``pinMode()``, and +.. subsequently made ``HIGH`` with :ref:`digitalWrite() +.. <lang-digitalwrite>`, this will set the internal pullup resistors, +.. which will *steer* the input pin to a HIGH reading unless it is pulled +.. LOW by external circuitry. + +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 0V. In this +state it can *sink* current, e.g. light an LED that is connected +through a series resistor to +3.3V, 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 +^^^^^ + +Maple (STM32) 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 extremely small demands on the circuit +that they are sampling. 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. STM32 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 3.3V power rails. The amount of current +provided by an STM32 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 (or more properly speaking, integer *literals*) are +numbers used directly in a sketch, like ``123``. By default, an +integer literal 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 literals are treated as base 10 (decimal) integers, +but special notation (formatters) may be used to enter numbers in +other bases. These are summarized 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. Their use in new +programs is discouraged. + +.. _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`` (this is a :ref:`GCC +<arm-gcc>` extension; it's not standard C++). + +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 + interpret it in octal. + +.. _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 +may be typed in upper or lower case (a-f). + +For example, the hexadecimal literal ``0x101`` is two hundred fifty +seven: 1×16\ :sup:`2` + 0×16\ :sup:`1` + 1×16\ :sup:`0` = 257. + +The hexadecimal literal ``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>`, with the attendant :ref:`limitations in values +<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 +------------------------ + +Similar to integer literals, floating point constants (properly: +floating-point *literals*) are used to make code more readable. +Floating point literals are swapped at compile time for the value to +which the expression evaluates. + +A floating point literal is any number which includes a decimal point. +For instance, ``3.0`` is a floating-point literal for the number 3. +By default, a floating-point literal is a :ref:`double <lang-double>`. +In order for the literal to be interpreted as a :ref:`float +<lang-float>`, you can write ``f`` directly after it. For example, +``3.0f`` is a floating-point literal 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 literal + - 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 +------------------------ + +This section documents constants whose value might change across +different LeafLabs boards. You can use these constants to help ensure +that your code will be portable across different boards. + +.. TODO replace "upcoming" when Mini, Native come out + +.. _lang-constants-led: + +- ``BOARD_LED_PIN``: the number of the pin which connects to the + built-in LED. On the Maple, this is pin 13, but it's not guaranteed + to be the same in upcoming boards like the Maple Mini. + +.. _lang-constants-but: + +- ``BOARD_BUTTON_PIN``: the number of the pin which connects to the + built-in button (labeled "BUT"). On the Maple, this is pin 38, but + it's not guaranteed to be the same in other boards. + +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>` + +.. include:: 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..d19b61c --- /dev/null +++ b/docs/source/lang/api/constrain.rst @@ -0,0 +1,69 @@ +.. 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:: 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..3fbb0af --- /dev/null +++ b/docs/source/lang/api/cos.rst @@ -0,0 +1,32 @@ +.. _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:: 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..90ca268 --- /dev/null +++ b/docs/source/lang/api/delay.rst @@ -0,0 +1,72 @@ +.. 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 +------- + +:: + + int ledPin = 13; // LED connected to pin 13 + + void setup() { + pinMode(ledPin, OUTPUT); // sets the digital pin as output + } + + void loop() { + digitalWrite(ledPin, HIGH); // sets the LED on + delay(1000); // waits for a second + digitalWrite(ledPin, 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:: 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..24a8286 --- /dev/null +++ b/docs/source/lang/api/delaymicroseconds.rst @@ -0,0 +1,65 @@ +.. 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:: 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..41642a7 --- /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 once breathe knows how to get the correct detachInterupt +.. (right now it's copying from HardwareTimer), replace with a +.. doxygenfunction directive + +.. 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>` + +.. include:: 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..3502587 --- /dev/null +++ b/docs/source/lang/api/digitalread.rst @@ -0,0 +1,58 @@ +.. 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 + + +Example +------- + +The following example turns the LED on when the button is pressed:: + + int ledPin = 13; // LED connected to Maple pin 13 + int buttonPin = 38; // BUT connected to Maple pin 38 + + void setup() { + pinMode(ledPin, OUTPUT); + pinMode(buttonPin, INPUT); + } + + void loop() { + int val = digitalRead(buttonPin); // reads the input pin + digitalWrite(ledPin, val); + } + +Note +---- + +If the pin isn't connected to anything, ``digitalRead()`` can return +either HIGH or LOW (and this can change in a way that seems random). + +Arduino Compatibility +--------------------- + +The Maple version of ``digitalRead()`` is compatible with Arduino. + + +See Also +-------- + +- :ref:`pinMode <lang-pinMode>` +- :ref:`digitalWrite <lang-digitalWrite>` + + + + + +.. include:: 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..6124d5f --- /dev/null +++ b/docs/source/lang/api/digitalwrite.rst @@ -0,0 +1,68 @@ +.. 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``. + +.. TODO make the following paragraphs true, but refer the reader to +.. INPUT_PULLUP and INPUT_PULLDOWN: + +If the pin is configured as an ``INPUT``, writing a ``HIGH`` value +with ``digitalWrite()`` will enable an internal pullup resistor. +Writing ``LOW`` will disable the pullup. The pullup resistor is enough +to light an LED dimly, so if LEDs appear to work, but very dimly, this +is a likely cause. The remedy is to set the pin to an output with the +:ref:`pinMode() <lang-pinmode>` function. + +.. note:: Pin 13 is harder to use as an input than the other pins + because it has an LED and resistor soldered to it in series. If you + enable its internal pull-up resistor, it will likely hang at around + 1.1V instead of the expected 3.3V because the onboard LED and + series resistor pull the voltage level down. If you must use pin 13 + as a digital input, use an external pull-down resistor. + +Example +------- + +The following example sets pin 13 to ``HIGH``, makes a one-second-long +delay, sets the pin back to ``LOW``, and delays again, causing a +blinking pattern:: + + + int ledPin = 13; // LED connected to digital pin 13 + + void setup() { + pinMode(ledPin, OUTPUT); // sets the digital pin as output + } + + void loop() { + digitalWrite(ledPin, HIGH); // sets the LED on + delay(1000); // waits for a second + digitalWrite(ledPin, LOW); // sets the LED off + delay(1000); // waits for a second + } + +See Also +-------- + +- :ref:`pinMode <lang-pinmode>` +- :ref:`digitalRead <lang-digitalread>` + +.. include:: cc-attribution.txt diff --git a/docs/source/lang/api/hardwarespi.rst b/docs/source/lang/api/hardwarespi.rst new file mode 100644 index 0000000..c71b2c3 --- /dev/null +++ b/docs/source/lang/api/hardwarespi.rst @@ -0,0 +1,152 @@ +.. highlight:: cpp + +.. _lang-hardwarespi: + +HardwareSPI +=========== + +This class is used for creating objects to manage the Maple's built-in +SPI ports. The Maple has two SPI ports. The relevant pins +corresponding to each port's logic signals are documented in the +following table (and on the Maple silkscreen): + +.. _lang-hardwarespi-pinout: + +.. list-table:: + :header-rows: 1 + + * - Port number + - NSS + - MOSI + - MISO + - SCK + + * - 1 + - 10 + - 11 + - 12 + - 13 + + * - 2 + - 31 + - 32 + - 33 + - 34 + +If you use a SPI port, you cannot simultaneously use its associated +pins for other purposes. + +Library Documentation +--------------------- + +HardwareSPI Class Reference +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +You can use the SPI interface by including a declaration ``HardwareSPI +Spi(number);`` at the start of the sketch or program. The ``number`` +must be either 1 or 2 and specifies which port to use. Once this is +done, you can call any of the methods documented here using +``Spi.method(arguments)``; for example, ``Spi.send(0x13)`` would send +the value ``0x13`` into the port buffer to be transmitted as soon as +possible. + +.. cpp:class:: HardwareSPI + + Class for interacting with SPI. + +.. cpp:function:: HardwareSPI::HardwareSPI(uint32 spi_num) + + Construct an object for managing a SPI peripheral. ``spi_num`` + must be 1 or 2; see the :ref:`table above + <lang-hardwarespi-pinout>` for pinout information. + +.. cpp:function:: void HardwareSPI::begin(SPIFrequency freq, uint32 endianness, uint32 mode) + + Configure the baudrate of the given SPI port and set up the header + pins appropriately. + + Parameters: + + - ``freq``: one of the ``SPIFrequency`` values, given :ref:`below + <lang-hardwarespi-spifrequency>`. + + - ``endianness``: either ``LSBFIRST`` (little-endian) or + ``MSBFIRST`` (big-endian). + + - ``mode``: one of 0, 1, 2, or 3, and specifies which SPI mode is + used. The mode number determines a combination of polarity and + phase according to the following table: + + .. list-table:: + :header-rows: 1 + + * - Mode + - Polarity + - Phase + + * - 0 + - 0 + - 0 + + * - 1 + - 0 + - 1 + + * - 2 + - 1 + - 0 + + * - 3 + - 1 + - 1 + + For more information on polarity and phase, see the + :ref:`external references, below <lang-hardwarespi-seealso>`. + +.. cpp:function:: void HardwareSPI::begin() + + A convenience ``begin()``, equivalent to ``begin(SPI_1_125MHZ, + MSBFIRST, 0)``. + +.. 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. + +SPI Speeds +^^^^^^^^^^ + +.. _lang-hardwarespi-spifrequency: + +The possible SPI speeds are configured using the ``SPIFrequency`` enum: + +.. doxygenenum:: SPIFrequency + +.. _lang-hardwarespi-seealso: + +See Also +-------- + +* `Wikipedia Article on Serial Peripheral Interface Bus (SPI) + <http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus>`_ +* `Arduino reference on SPI + <http://www.arduino.cc/playground/Code/Spi>`_ +* `Hardcore SPI on Arduino <http://klk64.com/arduino-spi/>`_ by kik64 +* STMicro documentation for STM32F103RB microcontroller: + + * `Datasheet <http://www.st.com/stonline/products/literature/ds/13587.pdf>`_ (pdf) + * `Reference Manual <http://www.st.com/stonline/products/literature/rm/13902.pdf>`_ (pdf) + + diff --git a/docs/source/lang/api/hardwaretimer.rst b/docs/source/lang/api/hardwaretimer.rst new file mode 100644 index 0000000..3e5424c --- /dev/null +++ b/docs/source/lang/api/hardwaretimer.rst @@ -0,0 +1,370 @@ +.. highlight:: cpp + +.. _lang-hardwaretimer: + +HardwareTimer +============= + +This class defines the public API for interfacing with the STM32's +built-in timer peripherals. More information on these peripherals +(including code examples) is available in the :ref:`timers reference +<timers>`. + +Library Documentation +--------------------- + +HardwareTimer Class Reference +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +To interact with a particular timer, call one of the methods +documented below on one of the predefined ``HardwareTimer`` instances. +For example, to set the prescale factor on timer 1 to 5, call +``Timer1.setPrescaleFactor(5)``. + +.. cpp:class:: HardwareTimer + + Class for interacting with a timer. There are four predefined + instances available on the Maple: ``Timer1``, ``Timer2``, + ``Timer3``, and ``Timer4``. + +.. _lang-hardwaretimer-attachinterrupt: + +.. cpp:function:: void HardwareTimer::attachInterrupt(int channel, voidFuncPtr handler) + + Attach an interrupt handler to the given ``channel``. This + interrupt handler will be called when the timer's counter reaches + the given channel :ref:`compare <lang-hardwaretimer-setcompare>` + value. + + ``handler`` should be a function which takes no arguments and has + :ref:`void <lang-void>` value; i.e. it should have signature :: + + void handler(void); + + You can later detach the interrupt using :ref:`detachInterrupt() + <lang-hardwaretimer-detachinterrupt>`. + + .. note:: The function (often called an *interrupt service + routine*, or ISR) should attempt to return as quickly as + possible. :ref:`Blinking the LED <lang-toggleled>`, some + logic, :ref:`PWM <pwm>` updates, and :ref:`Serial + <lang-serial>` writes are fine; writing to + :ref:`SerialUSB <lang-serialusb>` or :ref:`waiting + <lang-waitforbuttonpress>` for user input can take a long + time and prevent other interrupts from firing on time. + + Tip: if you have a :ref:`delay() <lang-delay>` in your + ISR, you're probably doing it wrong. + +.. cpp:function:: void HardwareTimer::attachCompare1Interrupt(voidFuncPtr handler) + + Equivalent to :ref:`attachInterrupt + <lang-hardwaretimer-attachinterrupt>`\ ``(1, handler)``. + +.. cpp:function:: void HardwareTimer::attachCompare2Interrupt(voidFuncPtr handler) + + Equivalent to :ref:`attachInterrupt + <lang-hardwaretimer-attachinterrupt>`\ ``(2, handler)``. + +.. cpp:function:: void HardwareTimer::attachCompare3Interrupt(voidFuncPtr handler) + + Equivalent to :ref:`attachInterrupt + <lang-hardwaretimer-attachinterrupt>`\ ``(3, handler)``. + +.. cpp:function:: void HardwareTimer::attachCompare4Interrupt(voidFuncPtr handler) + + Equivalent to :ref:`attachInterrupt + <lang-hardwaretimer-attachinterrupt>`\ ``(4, handler)``. + +.. _lang-hardwaretimer-setchannelmode: + +.. cpp:function:: void HardwareTimer::setChannelMode(int channel, TimerMode mode) + + Set the given channel of this timer to the given :ref:`mode + <lang-hardwaretimer-modes>`. The parameter ``channel`` is one of + 1, 2, 3, and 4, and corresponds to the compare channel you would + like to set. Refer to the full :ref:`pin mapping table + <pin-mapping-mega-table>` to match up timer channels and pin + numbers. + +.. cpp:function:: void HardwareTimer::setChannel1Mode(TimerMode mode) + + Equivalent to :ref:`setChannelMode <lang-hardwaretimer-setchannelmode>`\ + ``(1, mode)``. + +.. cpp:function:: void HardwareTimer::setChannel2Mode(TimerMode mode) + + Equivalent to :ref:`setChannelMode <lang-hardwaretimer-setchannelmode>`\ + ``(2, mode)``. + +.. cpp:function:: void HardwareTimer::setChannel3Mode(TimerMode mode) + + Equivalent to :ref:`setChannelMode <lang-hardwaretimer-setchannelmode>`\ + ``(3, mode)``. + +.. cpp:function:: void HardwareTimer::setChannel4Mode(TimerMode mode) + + Equivalent to :ref:`setChannelMode <lang-hardwaretimer-setchannelmode>`\ + ``(4, mode)``. + +.. _lang-hardwaretimer-getcompare: + +.. cpp:function:: uint16 HardwareTimer::getCompare(int channel) + + Gets the compare value for the given ``channel``, from 1 to 4. See + :ref:`setCompare() <lang-hardwaretimer-setcompare>`. + +.. cpp:function:: uint16 HardwareTimer::getCompare1() + + Equivalent to :ref:`getCompare <lang-hardwaretimer-getcompare>`\ + ``(1, mode)``. + +.. cpp:function:: uint16 HardwareTimer::getCompare2() + + Equivalent to :ref:`getCompare <lang-hardwaretimer-getcompare>`\ + ``(2, mode)``. + +.. cpp:function:: uint16 HardwareTimer::getCompare3() + + Equivalent to :ref:`getCompare <lang-hardwaretimer-getcompare>`\ + ``(3, mode)``. + +.. cpp:function:: uint16 HardwareTimer::getCompare4() + + Equivalent to :ref:`getCompare <lang-hardwaretimer-getcompare>`\ + ``(4, mode)``. + +.. _lang-hardwaretimer-setcompare: + +.. cpp:function:: void HardwareTimer::setCompare(int channel, uint16 compare) + + Sets the compare value for the given ``channel`` to ``compare``. + If ``compare`` is greater than this timer's overflow value, it will + be truncated to the overflow value. The default compare value is + 65,535 (the largest unsigned 16-bit integer value). + + When the counter reaches this value the interrupt for this channel + will fire if the given ``channel`` :ref:`mode + <lang-hardwaretimer-setchannelmode>` is ``TIMER_OUTPUTCOMPARE`` and + an interrupt is :ref:`attached + <lang-hardwaretimer-attachinterrupt>`. + + By default, this only changes 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. + +.. cpp:function:: void HardwareTimer::setCompare1(uint16 compare) + + Equivalent to :ref:`setCompare <lang-hardwaretimer-setcompare>`\ + ``(1, compare)``. + +.. cpp:function:: void HardwareTimer::setCompare2(uint16 compare) + + Equivalent to :ref:`setCompare <lang-hardwaretimer-setcompare>`\ + ``(2, compare)``. + +.. cpp:function:: void HardwareTimer::setCompare3(uint16 compare) + + Equivalent to :ref:`setCompare <lang-hardwaretimer-setcompare>`\ + ``(3, compare)``. + +.. cpp:function:: void HardwareTimer::setCompare4(uint16 compare) + + Equivalent to :ref:`setCompare <lang-hardwaretimer-setcompare>`\ + ``(4, compare)``. + +.. cpp:function:: uint16 HardwareTimer::getCount() + + Gets the current timer count. Due to function call overhead, the + return value will be increasingly accurate with smaller prescale + values. Also see :ref:`setCount() <lang-hardwaretimer-setcount>`. + +.. _lang-hardwaretimer-setcount: + +.. cpp:function:: void HardwareTimer::setCount(uint16 val) + + Set the timer's current count to ``val``. + + Note that there is some function call overhead associated with + calling this method, so using it is not a robust way to get + multiple timers to share a count value. + + If ``val`` exceeds the timer's :ref:`overflow value + <lang-hardwaretimer-getoverflow>`, it is truncated to the overflow + value. + + +.. _lang-hardwaretimer-detachinterrupt: + +.. cpp:function:: void HardwareTimer::detachInterrupt(int channel) + + Remove the interrupt handler attached to the given ``channel``, if + any. The handler will no longer be called by this timer. + +.. cpp:function:: void HardwareTimer::detachCompare1Interrupt() + + Equivalent to :ref:`detachInterrupt + <lang-hardwaretimer-detachinterrupt>`\ ``(1)``. + +.. cpp:function:: void HardwareTimer::detachCompare2Interrupt() + + Equivalent to :ref:`detachInterrupt + <lang-hardwaretimer-detachinterrupt>`\ ``(2)``. + +.. cpp:function:: void HardwareTimer::detachCompare3Interrupt() + + Equivalent to :ref:`detachInterrupt + <lang-hardwaretimer-detachinterrupt>`\ ``(3)``. + +.. cpp:function:: void HardwareTimer::detachCompare4Interrupt() + + Equivalent to :ref:`detachInterrupt + <lang-hardwaretimer-detachinterrupt>`\ ``(4)``. + +.. _lang-hardwaretimer-generateupdate: + +.. cpp:function:: void HardwareTimer::generateUpdate() + + Re-initializes the counter (to 0 in upcounting mode, which is the + default), and generates an update of the prescale and overflow + registers. + +.. _lang-hardwaretimer-getoverflow: + +.. cpp:function:: uint16 HardwareTimer::getOverflow() + + Gets the timer's overflow value. See :ref:`setOverflow() + <lang-hardwaretimer-setoverflow>`. + +.. _lang-hardwaretimer-setoverflow: + +.. cpp:function:: void HardwareTimer::setOverflow(uint16 val) + + Sets the timer overflow (or "reload") value to ``val``. + + When the timer's counter reaches this, value it resets to + zero. Its default value is 65535 (the largest unsigned 16-bit + integer); setting the overflow to anything lower will cause + interrupts to be called more frequently (see :ref:`setPeriod() + <lang-hardwaretimer-setperiod>` function for a shortcut). + + After the next :ref:`timer update + <lang-hardwaretimer-generateupdate>`, this number will be the + maximum value for the timer's channel compare values. + +.. _lang-hardwaretimer-pause: + +.. cpp:function:: void HardwareTimer::pause() + + Stop the timer's counter, without affecting its configuration. + + The timer will no longer count or fire interrupts after this + function is called, until it is resumed. This function is useful + during timer setup periods, in order to prevent interrupts from + firing before the timer is fully configured. + + Note that there is some function call overhead associated with this + method, so using it in concert with :ref:`resume() + <lang-hardwaretimer-resume>` is not a robust way to align multiple + timers to the same count value. + +.. _lang-hardwaretimer-setperiod: + +.. cpp:function:: uint16 HardwareTimer::setPeriod(uint32 microseconds) + + Configure the :ref:`prescaler + <lang-hardwaretimer-getprescalefactor>` and :ref:`overflow + <lang-hardwaretimer-getoverflow>` values to generate a timer reload + with a period as close to the given number of ``microseconds`` as + possible. + + The return value is the new overflow value, which may be used to + set channel compare values. However, if a clock that fires an + interrupt every given number of microseconds is all that is + desired, and the relative "phases" are unimportant, channel compare + values may all be set to 1. + +.. _lang-hardwaretimer-getprescalefactor: + +.. cpp:function:: uint16 HardwareTimer::getPrescaleFactor() + + Returns the timer's prescale factor. See + :ref:`setPrescaleFactor() <lang-hardwaretimer-setprescalefactor>`. + +.. _lang-hardwaretimer-setprescalefactor: + +.. cpp:function:: void HardwareTimer::setPrescaleFactor(uint16 factor) + + Set the timer's prescale factor to ``factor``. + + The prescaler acts as a clock divider to slow down the rate at + which the counter increments. + + For example, the system clock rate is 72MHz, so the counter will + reach 65535 in (13.89 nanoseconds) × (65535 counts) = (910.22 + microseconds), or about a thousand times a second. If the + prescaler equals 1098, then the clock rate is effectively 72MHz / + 1098 = 65.56KHz, and the counter will reach 65536 in (15.25 + microseconds) × (65536 counts) = (0.999 seconds), or about once + per second. + + The :ref:`setPeriod() <lang-hardwaretimer-setperiod>` method may + also be used as a convenient alternative. + +.. _lang-hardwaretimer-resume: + +.. cpp:function:: void HardwareTimer::resume() + + Resume a paused timer, without affecting its configuration. + + The timer will resume counting and firing interrupts as + appropriate. + + Note that there is some function call overhead associated with + using this method, so using it in concert with :ref:`pause() + <lang-hardwaretimer-pause>` is not a robust way to align multiple + timers to the same count value. + +.. cpp:function:: timer_dev_num HardwareTimer::getTimerNum() + + Returns the :ref:`timer device number + <lang-hardwaretimer-timer-dev-num>` associated with the timer. For + example, ``Timer1.getTimerNum()`` would return ``TIMER1``. + + In most cases, you should not need to use this function. If you do + use it, be careful; the constant ``TIMER1`` is *not equal* to the + number 1; similarly, ``TIMER2`` is *not* the number 2, etc. Be + sure to refer to the timer device number by name. + +.. _lang-hardwaretimer-modes: + +Timer Modes +^^^^^^^^^^^ +.. doxygenenum:: TimerMode + +.. _lang-hardwaretimer-timer-dev-num: + +Timer Device Numbers +^^^^^^^^^^^^^^^^^^^^ + +These provide a lower-level interface for interacting with timers. +They are mostly useful in context with the :ref:`getTimer() +<lang-hardwaretimer-gettimer>` function. **Be careful** when using +these not to confuse e.g. ``TIMER1`` with the number 1; they are +different. + +.. doxygenenum:: timer_dev_num + +.. _lang-hardwaretimer-convenience: + +.. _lang-hardwaretimer-gettimer: + +Other Functions +^^^^^^^^^^^^^^^ +.. doxygenfunction:: getTimer diff --git a/docs/source/lang/api/highbyte.rst b/docs/source/lang/api/highbyte.rst new file mode 100644 index 0000000..50a1fa6 --- /dev/null +++ b/docs/source/lang/api/highbyte.rst @@ -0,0 +1,59 @@ +.. 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:: 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..dbff0c9 --- /dev/null +++ b/docs/source/lang/api/isbuttonpressed.rst @@ -0,0 +1,17 @@ +.. _lang-isbuttonpressed: + +isButtonPressed() +================= + +Check whether the board's built-in button (labeled BUT on the +silkscreen) is pressed. + +Library Documentation +--------------------- + +.. doxygenfunction:: isButtonPressed + +See Also +-------- + +- :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..d8f6183 --- /dev/null +++ b/docs/source/lang/api/loop.rst @@ -0,0 +1,45 @@ +.. 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:: 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..58e622f --- /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:: 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..79122b3 --- /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:: 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..d38eebe --- /dev/null +++ b/docs/source/lang/api/max.rst @@ -0,0 +1,65 @@ +.. 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 version of ``max()`` is compatible with Arduino. + +See Also +-------- + +- :ref:`min() <lang-min>` +- :ref:`constrain() <lang-constrain>` + + +.. include:: 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..f12976b --- /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:: 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..0288c56 --- /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 + Serial.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:: 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..1245f6f --- /dev/null +++ b/docs/source/lang/api/min.rst @@ -0,0 +1,66 @@ +.. 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:: 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..03cbcfa --- /dev/null +++ b/docs/source/lang/api/pinmode.rst @@ -0,0 +1,79 @@ +.. 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 +------- + +:: + + int ledPin = 13; // LED connected to digital pin 13 + + void setup() { + pinMode(ledPin, OUTPUT); // sets the digital pin as output + } + + void loop() { + digitalWrite(ledPin, HIGH); // sets the LED on + delay(1000); // waits for a second + digitalWrite(ledPin, 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: + +The libmaple implementation of ``pinMode()`` supports the ``INPUT`` +and ``OUTPUT`` modes with semantics identical to that of the Arduino +function (however, be advised that the Maple, as a 3.3V device, will +only drive 3.3V to an ``OUTPUT`` pin that has been set ``HIGH``). + +``INPUT_ANALOG`` and ``PWM`` modes were added because the Maple does +not distinguish between analog and digital pins the same way the +Arduino does. Unlike the Arduino, you **must call** ``pinMode()`` to +set up a pin for these purposes before a call to, e.g., +:ref:`lang-analogRead`. In practice, this should only add a few lines +to your :ref:`lang-setup` function. + +.. TODO 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-constants` +- :ref:`lang-digitalwrite` +- :ref:`lang-digitalread` +- Maple :ref:`GPIO <gpio>` reference page + + + +.. include:: 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..4280400 --- /dev/null +++ b/docs/source/lang/api/pow.rst @@ -0,0 +1,23 @@ +.. _lang-pow: + +pow() +===== + +Calculates the value of a number raised to a power. + +Library Documentation +--------------------- + +.. doxygenfunction:: pow + +.. TODO LATER some examples + +See Also +-------- + +- :ref:`sqrt() <lang-sqrt>` +- :ref:`float <lang-float>` +- :ref:`double <lang-double>` + + +.. include:: 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..9d50077 --- /dev/null +++ b/docs/source/lang/api/pwmwrite.rst @@ -0,0 +1,55 @@ +.. 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. + +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. + +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>` diff --git a/docs/source/lang/api/random.rst b/docs/source/lang/api/random.rst new file mode 100644 index 0000000..dd8871d --- /dev/null +++ b/docs/source/lang/api/random.rst @@ -0,0 +1,73 @@ +.. highlight:: cpp + +.. _lang-random: + +random() +======== + +The ``random()`` function generates pseudo-random numbers. + +Library Documentation +--------------------- + +.. FIXME keep tracking Sphinx/Breathe's ability to reference +.. overloaded functions so we can use doxygenfunction instead of +.. manually documenting. + +.. 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:: 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..d0a15b7 --- /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:: 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..ca89b31 --- /dev/null +++ b/docs/source/lang/api/serial.rst @@ -0,0 +1,226 @@ +.. _lang-serial: + +Serial Ports (``Serial1``, ``Serial2``, ``Serial3``) +==================================================== + +Used for communication between the Maple board and a computer or other +devices. + +.. contents:: Contents + :local: + +Introduction +------------ + +The Maple has three serial ports (also known as a UARTs or USARTs): +``Serial1``, ``Serial2``, and ``Serial3``. They communicate using the +pins summarized in the following table: + +.. list-table:: + :header-rows: 1 + + * - Serial port + - TX, RX, CK + - CTS, RTS (if present) + + * - ``Serial1`` + - 7, 8, 6 + - + + * - ``Serial2`` + - 1, 0, 10 + - 2, 3 + + * - ``Serial3`` + - 29, 30, 31 + - 32, 33 + +Thus, if you use a particular serial port, you cannot also use its +communication pins for other purposes at the same time. + +If you want to communicate with the Maple using the provided USB port, +use :ref:`SerialUSB <lang-serialusb>` instead. + +To use them to communicate with an external TTL serial device, connect +the TX pin to your device's RX pin, the RX to your device's TX pin, +and the ground of your Maple 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. + + +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:: 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:: 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:: HardwareSerial::flush() + + Removes the contents of the Serial's associated USART RX FIFO. + That is, clears any buffered characters, so that the next character + read is guaranteed to be new. + +.. cpp:function:: HardwareSerial::print(unsigned char b) + + Print the given byte over the USART. + +.. cpp:function:: HardwareSerial::print(char c) + + Print the given character over the USART. 7-bit clean characters + are typically interpreted as ASCII text. + +.. cpp:function:: HardwareSerial::print(const char *str) + + Print the given null-terminated string over the USART. + +.. cpp:function:: 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:: HardwareSerial::print(unsigned int n) + + Print the argument's digits over the USART, in decimal format. + +.. cpp:function:: 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:: HardwareSerial::print(unsigned long n) + + Print the argument's digits over the USART, in decimal format. + +.. cpp:function:: 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:: HardwareSerial::print(double n) + + Print ``n``, accurate to 2 digits after the decimal point. + +.. _lang-serial-println: + +.. cpp:function:: HardwareSerial::println(char c) + + Like ``print(c)``, followed by ``"\r\n"``. + +.. cpp:function:: HardwareSerial::println(const char *c) + + Like ``print(c)``, followed by ``"\r\n"``. + +.. cpp:function:: HardwareSerial::println(unsigned char b) + + Like ``print(b)``, followed by ``"\r\n"``. + +.. cpp:function:: HardwareSerial::println(int n) + + Like ``print(n)``, followed by ``"\r\n"``. + +.. cpp:function:: HardwareSerial::println(unsigned int n) + + Like ``print(n)``, followed by ``"\r\n"``. + +.. cpp:function:: HardwareSerial::println(long n) + + Like ``print(n)``, followed by ``"\r\n"``. + +.. cpp:function:: HardwareSerial::println(unsigned long n) + + Like ``print(n)``, followed by ``"\r\n"``. + +.. cpp:function:: HardwareSerial::println(long n, int base) + + Like ``print(n, b)``, followed by ``"\r\n"``. + +.. cpp:function:: HardwareSerial::println(double n) + + Like ``print(n)``, followed by ``"\r\n"``. + +.. cpp:function:: HardwareSerial::println() + + Prints ``"\r\n"`` over the USART. + +.. cpp:function:: HardwareSerial::write(unsigned char ch) + + Sends one character over the USART. 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:: 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:: 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. + +Arduino Compatibility Note +-------------------------- + +Unlike the Arduino, none of the Maple's serial ports is connected to +the USB port on the Maple board (for that, use :ref:`SerialUSB +<lang-serialusb>`). Thus, to use these pins to communicate with your +personal computer, you will need an additional USB-to-serial adaptor. + +.. TODO LATER 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:: 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..3bb8c00 --- /dev/null +++ b/docs/source/lang/api/serialusb.rst @@ -0,0 +1,243 @@ +.. 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 (text read/write). The emulated terminal is relatively slow +and inefficient; 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 the emulated on a computer, your program + will run much, 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 13 + + void setup() { + /* Set up the LED to blink */ + pinMode(LED_PIN, OUTPUT); + } + + void loop() { + // LED will stay off if we are disconnected; + // will blink quickly if USB is unplugged (battery 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() will fully + // many times, 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 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..837ddd6 --- /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:: 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..398b8f3 --- /dev/null +++ b/docs/source/lang/api/sin.rst @@ -0,0 +1,32 @@ +.. _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:: 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..bd32648 --- /dev/null +++ b/docs/source/lang/api/sq.rst @@ -0,0 +1,46 @@ +.. 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:: 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..4bbe0db --- /dev/null +++ b/docs/source/lang/api/tan.rst @@ -0,0 +1,31 @@ +.. _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:: 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..0cc20c2 --- /dev/null +++ b/docs/source/lang/api/toggleled.rst @@ -0,0 +1,17 @@ +.. _lang-toggleled: + +toggleLED() +=========== + +Switches the LED from off to on, or on to off. + +Library Documentation +--------------------- + +.. doxygenfunction:: toggleLED + +See Also +-------- + +- :ref:`BOARD_LED_PIN <lang-constants-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..276bb6a --- /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>`. On the Maple, the only place that this is +likely to occur is in sections of code associated with 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:: 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..34c5066 --- /dev/null +++ b/docs/source/lang/api/waitforbuttonpress.rst @@ -0,0 +1,17 @@ +.. _lang-waitforbuttonpress: + +waitForButtonPress() +==================== + +Wait for the board's built-in button (labeled BUT on the silkscreen) +to be pressed, possibly with timeout. + +Library Documentation +--------------------- + +.. doxygenfunction:: waitForButtonPress + +See Also +-------- + +- :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..e100140 --- /dev/null +++ b/docs/source/lang/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/arithmetic.rst b/docs/source/lang/cpp/arithmetic.rst new file mode 100644 index 0000000..7e8c3fc --- /dev/null +++ b/docs/source/lang/cpp/arithmetic.rst @@ -0,0 +1,127 @@ +.. 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 `libmaple_types.h + <http://github.com/leaflabs/libmaple/blob/master/libmaple/libmaple_types.h>`_\ + . + +- :ref:`sizeof <lang-sizeof>`\ () + + +.. include:: 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..30a818f --- /dev/null +++ b/docs/source/lang/cpp/array.rst @@ -0,0 +1,123 @@ +.. 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:: 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..f9430b4 --- /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:: 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..e1c8de0 --- /dev/null +++ b/docs/source/lang/cpp/bitshift.rst @@ -0,0 +1,144 @@ +.. 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:: 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..28fe6bf --- /dev/null +++ b/docs/source/lang/cpp/bitwisemath.rst @@ -0,0 +1,186 @@ +.. 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 blink digital pin 13 (the LED pin on Maple):: + + // Blink Maple LED pin + + int led_pin = 13; + int toggle = 0; + + // demo for Exclusive OR + void setup(){ + pinMode(led_pin, OUTPUT); + } + + void loop(){ + toggle = toggle ^ 1; + digitalWrite(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:: 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..8d6aa5c --- /dev/null +++ b/docs/source/lang/cpp/boolean.rst @@ -0,0 +1,91 @@ +.. 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:: 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..6051b8c --- /dev/null +++ b/docs/source/lang/cpp/booleanvariables.rst @@ -0,0 +1,54 @@ +.. 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 +------- + +:: + + int ledPin = 13; // LED on pin 13 + int switchPin = 12; // momentary switch on 12, other side connected to ground + + // running is a boolean variable: + bool running = false; + + void setup() { + pinMode(ledPin, OUTPUT); + pinMode(switchPin, INPUT); + digitalWrite(switchPin, HIGH); // turn on pullup resistor + } + + void loop() { + if (digitalRead(switchPin) == LOW) { + // switch is pressed - pullup keeps pin high normally + delay(100); // delay to debounce switch + running = !running; // toggle running variable + digitalWrite(ledPin, running) // indicate via LED + } + } + +See also +-------- + + +- :ref:`Boolean constants <lang-constants-bool>` +- :ref:`Boolean operators <lang-boolean>` +- :ref:`Variables <lang-variables>` + + +.. include:: 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..ce8ac17 --- /dev/null +++ b/docs/source/lang/cpp/break.rst @@ -0,0 +1,35 @@ +.. 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:: 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..a7349e6 --- /dev/null +++ b/docs/source/lang/cpp/built-in-types.rst @@ -0,0 +1,95 @@ +.. 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 + + Synonym for ``char``. + +.. cpp:type:: uint8 + + Synonym for ``unsigned char``. + +.. cpp:type:: int16 + + Synonym for ``short``. + +.. cpp:type:: uint16 + + Synonym for ``unsigned short``. + +.. cpp:type:: int32 + + Synonym for ``int``. + +.. cpp:type:: uint32 + + Synonym for ``unsigned int`` + +.. cpp:type:: int64 + + Synonym for ``long long`` + +.. cpp:type:: uint64 + + 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. + +Other Types +----------- + +.. cpp:type:: voidFuncPtr + + Pointer to a function that takes no arguments and returns nothing, i.e. + + :: + + typedef void (*voidFuncPtr)(void); + diff --git a/docs/source/lang/cpp/byte.rst b/docs/source/lang/cpp/byte.rst new file mode 100644 index 0000000..45c9d5f --- /dev/null +++ b/docs/source/lang/cpp/byte.rst @@ -0,0 +1,34 @@ +.. 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:: 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..b3f0de2 --- /dev/null +++ b/docs/source/lang/cpp/bytecast.rst @@ -0,0 +1,50 @@ +.. 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:: 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..b8747f3 --- /dev/null +++ b/docs/source/lang/cpp/char.rst @@ -0,0 +1,50 @@ +.. 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..a480dec --- /dev/null +++ b/docs/source/lang/cpp/charcast.rst @@ -0,0 +1,36 @@ +.. 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:: 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..c5f118a --- /dev/null +++ b/docs/source/lang/cpp/comments.rst @@ -0,0 +1,67 @@ +.. 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:: 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..b24355f --- /dev/null +++ b/docs/source/lang/cpp/comparison.rst @@ -0,0 +1,87 @@ +.. 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:: 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..420f1db --- /dev/null +++ b/docs/source/lang/cpp/compoundarithmetic.rst @@ -0,0 +1,44 @@ +.. 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:: 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..8231130 --- /dev/null +++ b/docs/source/lang/cpp/compoundbitwise.rst @@ -0,0 +1,230 @@ +.. 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..52de85f --- /dev/null +++ b/docs/source/lang/cpp/const.rst @@ -0,0 +1,52 @@ +.. 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:: 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..13d1815 --- /dev/null +++ b/docs/source/lang/cpp/continue.rst @@ -0,0 +1,32 @@ +.. 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:: 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..a4bd3dc --- /dev/null +++ b/docs/source/lang/cpp/curly-braces.rst @@ -0,0 +1,109 @@ +.. 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 + +.. TODO remove this once IDE 0.1.0 released + +.. [#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:: 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..677390d --- /dev/null +++ b/docs/source/lang/cpp/define.rst @@ -0,0 +1,56 @@ +.. 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 LED_PIN 13 + // The compiler will replace any mention of LED_PIN with + // the value 3 at compile time. + +See Also +-------- +- :ref:`const <lang-const>` + + +.. include:: 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..1527778 --- /dev/null +++ b/docs/source/lang/cpp/double.rst @@ -0,0 +1,48 @@ +.. _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:: 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..16a9907 --- /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:: 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..fe92226 --- /dev/null +++ b/docs/source/lang/cpp/dowhile.rst @@ -0,0 +1,27 @@ +.. 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:: 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..6937c8c --- /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:: 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..4766478 --- /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:: 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..71c5aca --- /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:: 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..ff2f248 --- /dev/null +++ b/docs/source/lang/cpp/goto.rst @@ -0,0 +1,130 @@ +.. 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:: 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..bef89e2 --- /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(ledPin, HIGH); + + if (x > 120) + digitalWrite(ledPin, HIGH); + + if (x > 120) { + digitalWrite(ledPin, HIGH); + } + +However, the following two examples are different:: + + // example 1: two lines of code in the if body + if (x > 120) { + digitalWrite(ledPin1, HIGH); + digitalWrite(ledPin2, HIGH); + } + + // example 2: one line of code in the if body, and + // another line of code after the if statement + if (x > 120) + digitalWrite(ledPin1, HIGH); // this is in the if body + digitalWrite(ledPin2, 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:: 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..74fe7af --- /dev/null +++ b/docs/source/lang/cpp/include.rst @@ -0,0 +1,72 @@ +.. 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:: 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..6dffa80 --- /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:: 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..3e96b69 --- /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 ``ledPin``, +then giving it value 13:: + + int ledPin = 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..386fe14 --- /dev/null +++ b/docs/source/lang/cpp/intcast.rst @@ -0,0 +1,29 @@ +.. 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:: 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..f588fc6 --- /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:: 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..0ba56ed --- /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:: 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..289fba0 --- /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:: 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..0a42270 --- /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:: 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..b4ef5fd --- /dev/null +++ b/docs/source/lang/cpp/return.rst @@ -0,0 +1,61 @@ +.. 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:: 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..7b65bab --- /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:: 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..8164616 --- /dev/null +++ b/docs/source/lang/cpp/semicolon.rst @@ -0,0 +1,25 @@ +.. 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:: 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..eae509c --- /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:: 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..956a754 --- /dev/null +++ b/docs/source/lang/cpp/sqrt.rst @@ -0,0 +1,25 @@ +.. _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:: 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..5d1802e --- /dev/null +++ b/docs/source/lang/cpp/static.rst @@ -0,0 +1,57 @@ +.. 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:: 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..0a270da --- /dev/null +++ b/docs/source/lang/cpp/string.rst @@ -0,0 +1,128 @@ +.. highlight:: cpp + +.. _lang-string: + +Strings +======= + +Text strings can be represented in two ways. You can + +1. Use the :ref:`String <lang-stringclass>` data type, which is +part of the core as of version 0.0.9, or + +2. You can make a string out of an array of type :ref:`char +<lang-char>` and null-terminate it. + +This page describes the second method. + +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:: 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..b484bc5 --- /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:: 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..5b946ed --- /dev/null +++ b/docs/source/lang/cpp/unsignedchar.rst @@ -0,0 +1,33 @@ +.. 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:: 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..ad3e2f2 --- /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 +``ledPin``, then giving it value 13:: + + unsigned int ledPin = 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:: 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..910b7e4 --- /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:: 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..336d5ab --- /dev/null +++ b/docs/source/lang/cpp/variables.rst @@ -0,0 +1,170 @@ +.. 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:: 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..88c9c64 --- /dev/null +++ b/docs/source/lang/cpp/void.rst @@ -0,0 +1,33 @@ +.. 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() { + // ... + } + +.. TODO doc page on function declaration? + +.. include:: 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..9047d05 --- /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:: 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..485c9c5 --- /dev/null +++ b/docs/source/lang/unimplemented/notone.rst @@ -0,0 +1,50 @@ +.. _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/shiftout.rst b/docs/source/lang/unimplemented/shiftout.rst new file mode 100644 index 0000000..ff3852f --- /dev/null +++ b/docs/source/lang/unimplemented/shiftout.rst @@ -0,0 +1,136 @@ +.. _lang-shiftout: + +shiftOut() +========== + +Description +----------- + +Shifts out a byte of data one bit at a time. Starts from either the +most (i.e. the leftmost) or least (rightmost) significant bit. Each +bit is written in turn to a data pin, after which a clock pin is +pulsed to indicate that the bit is available. + + + +This is a software implementation; Arduino (as of 0019) also +provides an `SPI library <http://arduino.cc/en/Reference/SPI>`_ +that uses the hardware implementation. + + + +Syntax +------ + +shiftOut(dataPin, clockPin, bitOrder, value) + + + +Parameters +---------- + +dataPin: the pin on which to output each bit (*int*) + + + +clockPin: the pin to toggle once the **dataPin** has been set to +the correct value (*int*) + + + +bitOrder: which order to shift out the bits; either **MSBFIRST** or +**LSBFIRST**. +(Most Significant Bit First, or, Least Significant Bit First) + + + +value: the data to shift out. (*byte*) + + + +Returns +------- + +None + + + +Note +---- + +The **dataPin** and **clockPin** must already be configured as +outputs by a call to +`pinMode <http://arduino.cc/en/Reference/PinMode>`_\ (). + + + +**shiftOut** is currently written to output 1 byte (8 bits) so it +requires a two step operation to output values larger than 255. + +:: + + // Do this for MSBFIRST serial + int data = 500; + // shift out highbyte + shiftOut(dataPin, clock, MSBFIRST, (data >> 8)); + // shift out lowbyte + shiftOut(data, clock, MSBFIRST, data); + + // Or do this for LSBFIRST serial + data = 500; + // shift out lowbyte + shiftOut(dataPin, clock, LSBFIRST, data); + // shift out highbyte + shiftOut(dataPin, clock, LSBFIRST, (data >> 8)); + + + +Example +------- + +*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/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..f83bf6b --- /dev/null +++ b/docs/source/lang/unimplemented/tone.rst @@ -0,0 +1,81 @@ +.. _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:: /lang/cc-attribution.txt diff --git a/docs/source/language-index.rst b/docs/source/language-index.rst new file mode 100644 index 0000000..e160e2b --- /dev/null +++ b/docs/source/language-index.rst @@ -0,0 +1,40 @@ +.. _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 adaptations of the Arduino C++ documentation to the +.. Maple, and are intended as a minimal reference/refresher for +.. programmers familiar with the Arduino language. + +.. _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 in libmaple or not part of current release: + +.. toctree:: + :hidden: + + lang/unimplemented/notone.rst + lang/unimplemented/pulsein.rst + lang/unimplemented/shiftout.rst + lang/unimplemented/stringclass.rst + lang/unimplemented/stringobject.rst + lang/unimplemented/tone.rst diff --git a/docs/source/language.rst b/docs/source/language.rst new file mode 100644 index 0000000..2ebe03c --- /dev/null +++ b/docs/source/language.rst @@ -0,0 +1,444 @@ +.. highlight:: c++ + +.. _language: + +========================== + Maple 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 curious about the differences between the Wiring +language and C++ may wish to skip to the +:ref:`arduino_c_for_c_hackers`. + +.. contents:: Contents + :local: + +Unique Maple Additions +---------------------- + +.. _language-assert: + +``ASSERT(...)`` + The ``ASSERT()`` function can be very useful for basic program + debugging. The function 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 in intensity (it's noticeably different from blinking). The + debug information is printed at 9600 baud and consists of the + filename and line number where the particular assertion 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. + +.. _language-lang-docs: + +Maple Language Reference +------------------------ + +The following table summarizes the available core language features. +A more exhaustive index is available at the :ref:`language-index`. + ++--------------------------------------------+----------------------------------------------+---------------------------------------------------+ +| 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:`BOARD_LED_PIN <lang-constants-led>` | | | +| | :ref:`BOARD_BUTTON_PIN <lang-constants-but>`|* :ref:`isButtonPressed() <lang-isbuttonpressed>` | +|* :ref:`while <lang-while>` | | | +| |* :ref:`Constants |* :ref:`waitForButtonPress() | +|* :ref:`do...while <lang-dowhile>` | <lang-constants>` (:ref:`integers | <lang-waitforbuttonpress>` | +| | <lang-constants-integers>`, :ref:`floating | | +|* :ref:`break <lang-break>` | point <lang-constants-fp>`) |**Analog I/O** | +| | | | +|* :ref:`continue <lang-continue>` |**Data Types** |* :ref:`analogRead() <lang-analogread>` | +| | | | +|* :ref:`return <lang-return>` | The size of each datatype, 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) | | +| | |* shiftOut(): TODO | +|* :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 operator) | :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:`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) | | | +| | |**Looking for something else?** | +|* :ref:`- - <lang-increment>` | | | +| (decrement) | | See the :ref:`libraries` page for interfacing with| +| | | particular types of hardware. Maple links | +|* :ref:`+= <lang-compoundarithmetic>` | | against `newlib <http://sourceware.org/newlib/>`_ | +| (compound add) | | and allows the use of any of its functions; see | +| | | its documentation for more details. | +|* :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. However, they will be present in future versions: + +- `noTone() <http://www.arduino.cc/en/Reference/NoTone>`_ +- `pulseIn() <http://www.arduino.cc/en/Reference/PulseIn>`_ +- `shiftOut() <http://www.arduino.cc/en/Reference/ShiftOut>`_ +- `String <http://arduino.cc/en/Reference/StringObject>`_ +- `tone() <http://www.arduino.cc/en/Reference/Tone>`_ + +.. _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++ (although, +you C programmers should remember that `C++ is not a superset of C +<http://en.wikipedia.org/wiki/Compatibility_of_C_and_C%2B%2B>`_) 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. + +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 only other major +difference between Wiring and C++ is that Wiring doesn't support +dynamically allocated memory -- that is, ``new`` and ``delete`` won't +work. As of |today|, Maple only has 20 KB RAM, anyway, so it's +doubtful that static allocation is not what you want. + +The Wiring language also does not require you to define your own +``main`` method (in fact, it forbids you from doing so). Instead, you +are required to define two functions, ``setup`` and ``loop``, with +type signatures :: + + 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. 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>`_. An +upcoming rewrite of the IDE performs this preprocessing step +correctly, using a real 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 +<http://github.com/leaflabs/libmaple/blob/master/wirish/WProgram.h>`_ +(which includes the wirish and libmaple 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 a +``main()`` method. The final step of compilation provides this +method, which behaves roughly like:: + + int main(void) { + setup(); + 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() { + setup(); + while (true) loop(); + } + +(Recall that it's legal C++ for a function to be declared multiple +times, as long as it's defined exactly once). + + +Recommended Reading +------------------- + +* `newlib Documentation <http://sourceware.org/newlib/>`_ +* STMicro documentation for STM32F103RB microcontroller: + + * `Datasheet <http://www.st.com/stonline/products/literature/ds/13587.pdf>`_ (pdf) + * `Reference Manual <http://www.st.com/stonline/products/literature/rm/13902.pdf>`_ (pdf) + * `Programming Manual <http://www.st.com/stonline/products/literature/pm/15491.pdf>`_ (assembly language and register reference) diff --git a/docs/source/libmaple.rst b/docs/source/libmaple.rst new file mode 100644 index 0000000..8cc39a3 --- /dev/null +++ b/docs/source/libmaple.rst @@ -0,0 +1,41 @@ +.. highlight:: sh + +.. _libmaple: + +``libmaple`` +============ + +.. image:: /_static/img/libmaple-screenshot-small.png + :align: center + :alt: libmaple screenshot + +`LeafLabs libmaple <libmaple-libmaple>`_ is the low level library we +have developed for for the ARM Cortex-M3 chips manufactured by +STMicroelectronics used in the Maple boards (the `STM32F103x`_ +series). We found the generic peripheral libraries too painful to +build on top of, and reimplemented the functionality we needed in a +simpler (and less general) form. + +.. _libmaple-libmaple: http://github.com/leaflabs/libmaple +.. _STM32F103x: http://www.st.com/stonline/stappl/productcatalog/app?path=/pages/stcom/PcStComPartNumberSearch.searchPartNumber&search=stm32f103 + +This library is transparently included in the `Maple IDE +<http://leaflabs.com/docs/maple-ide/>`_, but we develop it separately +using good old Unix command line tools and release it for advanced +users who might chafe at the "sketch" programming model of the +IDE. Included are some examples, a Makefile, and the compatibility +wrappers and code to imitate the Arduino programming library. + +**Check out the latest source**:: + + git clone git://github.com/leaflabs/libmaple.git + +**Table of contents:** + +.. toctree:: + :maxdepth: 2 + + Guide to using GCC's ARM target <arm-gcc> + +.. TODO LATER create, style, and host a pure Doxygen libmaple +.. reference docs. This implies determining a stable API. diff --git a/docs/source/libraries.rst b/docs/source/libraries.rst new file mode 100644 index 0000000..7623963 --- /dev/null +++ b/docs/source/libraries.rst @@ -0,0 +1,194 @@ +.. 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 briefly summarizes the Arduino libraries that have been +ported to Maple. 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 are noted +in the description of the library. + +.. contents:: Contents + :local: + +.. toctree:: + :hidden: + + libs/servo.rst + +.. _libraries-servo: + +Servo +----- + +The Servo library is provided for convenient control of RC +servomotors. For more information, see the :ref:`Servo <libs-servo>` +reference. + +**Compatibility Note** + +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 +the servos with "bit-banged" :ref:`PWM <pwm>`, the Maple +implementation uses :ref:`timers <timers>` to drive the PWM directly. + +Consequently, **the Maple implementation only allows Servo instances +to** :ref:`attach <libs-servo-attach>` **to pins that support PWM**. + +To determine if a pin supports PWM (15 Maple pins do), you can either +check if "PWM" appears next to its number on the Maple silkscreen, or +consult the :ref:`pwmWrite() <lang-pwmwrite>` documentation. + +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 the :ref:`table provided in the timers +reference <timers-pin-channel-map>` to match up pins and timer +channels. + +Another difference: 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 true on success, and +false on failure (and this is its documented behavior). + +.. _libraries-liquid-crystal: + +LiquidCrystal +------------- + +.. TODO 0.0.10 make our own LiquidCrystal docs + +The LiquidCrystal library allows Maple to control LCD screens. For +more information, see the `Arduino LiquidCrystal documentation +<http://www.arduino.cc/en/Reference/LiquidCrystal>`_. + +**Compatibility Note** + +At this time, no incompatibilities between the Maple and Arduino +versions are known. Any observed differences should be considered +bugs, and reported on the forums. + +.. _libraries-wire: + +Wire +---- + +We provide a soft (bit-banged) implementation of the `Wire I2C library +<http://arduino.cc/en/Reference/WireBegin>`_. + +**Compatibility Note** + +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. Future enhancements will use +the hardware i2c peripheral on the stm32 as well as the DMA for +performance. Support for slave, smBUS, and multimaster modes are also +slated for inclusion in the enhanced Wire port. + +.. TODO 0.0.10 Wire docs in the cpp domain in own page under /libs/ + +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)``. + +.. 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/servo.rst b/docs/source/libs/servo.rst new file mode 100644 index 0000000..f92fd91 --- /dev/null +++ b/docs/source/libs/servo.rst @@ -0,0 +1,108 @@ +.. 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 ``$LIB_MAPLE_HOME/libraries/Servo/``. + +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); + +.. cpp:class:: Servo + + Class for controlling RC servomotors via :ref:`timers <timers>`. + +.. _libs-servo-attach: + +.. cpp:function:: bool Servo::attach(uint8 pin, uint16 min, uint16 max) + + Attach this Servo object to the given ``pin``. The pin must be + capable of PWM. You can check this by seeing if "PWM" is written + next to its number on the Maple silkscreen, or by consulting the + :ref:`pwmWrite() <lang-pwmwrite>` documentation. + + Sets this pin's :ref:`mode <lang-pinmode>` to :ref:`PWM + <lang-pinmode-wiringpinmode>`, and returns true if successful. + Does nothing and returns false if the pin doesn't support PWM. + + Parameter ``min`` is the pulse width corresponding to 0 degrees; + ``max`` is the pulse width corresponding to 180 degrees (both are + in microseconds). + +.. cpp:function:: bool Servo::attach(uint8 pin) + + Equivalent to :ref:`attach(pin, 544, 2400) <libs-servo-attach>`. + +.. _libs-servo-attached: + +.. cpp:function:: int Servo::attached() const + + If currently attached (via :ref:`attach() <libs-servo-attach>`) to + a pin, returns that pin's number. Returns ``NOT_ATTACHED`` + otherwise. + +.. cpp:function:: bool Servo::detach() + + If this Servo object is currently attached to pin, stops driving + the servo by setting a zero pulse width (this is accomplished by + setting the associated :ref:`channel mode + <lang-hardwaretimer-setchannelmode>` to ``TIMER_DISABLED``). + + Subsequently, calling :ref:`attached() <libs-servo-attached>` will + return ``NOT_ATTACHED``. + +.. cpp:function:: void Servo::write(unsigned int value) + + If ``value`` is less than ``SERVO_MAX_WRITE_ANGLE`` (which, for + Arduino compatibility, is 200), it's interpreted as an angle in + degrees. Otherwise, it's treated as a pulse width in microseconds. + + Drives the servo to target the given angle, based on a linear + interpolation of the ``min`` and ``max`` pulse widths determined + when :ref:`attach() <libs-servo-attach>` was called. + + Be aware that some (especially lower-cost) servos have fairly + non-linear maps between pulse width and target angle. Make sure to + test your motor before relying on this method. + +.. cpp:function:: void Servo::writeMicroseconds(uint16 pulseWidth) + + Drives the servo using a ``pulseWidth``-microsecond pulse. + + If ``pulseWidth`` is outside of the [``min``, ``max``\ ] pulse + width range set during :ref:`attach() <libs-servo-attach>`, it will + be clamped to lie in this range. + +.. cpp:function:: int Servo::read() const + + Returns the servo's target angle, in degrees. This will be clamped + to lie between 0 (when the pulse width is at most ``min``) and 180 + (when the pulse width is at least ``max``). + +.. cpp:function:: uint16 Servo::readMicroseconds() const + + Returns the pulse width of the wave currently driving the servo, in + microseconds. This will be clamped to lie in the [``min``, + ``max``\ ] pulse width range set during :ref:`attach() + <libs-servo-attach>`. diff --git a/docs/source/maple-ide-install.rst b/docs/source/maple-ide-install.rst new file mode 100644 index 0000000..92d1a96 --- /dev/null +++ b/docs/source/maple-ide-install.rst @@ -0,0 +1,162 @@ +.. 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 +-------- + +Choose the correct version for your operating system: + +.. list-table:: + :widths: 15 30 50 + :header-rows: 1 + + * - Platform + - Status + - IDE Package + * - Windows + - Tested on 32bit Windows XP + - `maple-ide-LATEST-windowsxp32.zip <http://static.leaflabs.com/pub/leaflabs/maple-ide/maple-ide-LATEST-windowsxp32.zip>`_ (about 75mb) + * - Linux + - Tested on Ubuntu 9.10 (64bit) and 10.04 (32bit) + - `maple-ide-LATEST-linux32.tgz <http://static.leaflabs.com/pub/leaflabs/maple-ide/maple-ide-LATEST-linux32.tgz>`_ (about 30mb) + + `maple-ide-LATEST-linux64.tgz <http://static.leaflabs.com/pub/leaflabs/maple-ide/maple-ide-LATEST-linux64.tgz>`_ (about 30mb) + * - Mac OSX + - Tested on Snow Leopard 10.6 (64bit and 32bit) + - `maple-ide-LATEST-macosx-10_6.dmg <http://static.leaflabs.com/pub/leaflabs/maple-ide/maple-ide-LATEST-macosx-10_6.dmg>`_ (about 40mb) + +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://fsf.org/>`_; we are grateful to the `Arduino +<http://arduino.cc/>`_, `CodeSourcery +<http://www.codesourcery.com/>`_, `GNU <http://gnu.org/>`_, and +`OpenMoko <http://openmoko.com/>`_ developers, as well as many others, +who allow us to reuse their software. + +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 +^^^^^^^ +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! + +.. note:: Note that while these instructions work on Windows XP, + changes in Windows 7 mean that you won't be able to install the IDE + without disabling driver signing on your computer. We're working + on resolving this situation. For now, `users on the forum have + reported some workarounds + <http://forums.leaflabs.com/topic.php?id=73>`_. + +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. Sun + Java 1.6 and OpenJDK 1.6 are known to work, and runtimes mostly + compatible with Sun 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 now need to +restart udev:: + + sudo /etc/init.d/udev restart + +This will grant members of the group ``plugdev`` read/write access to +Maple devices over USB. Make sure that you are in 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..08fa5c1 --- /dev/null +++ b/docs/source/maple-quickstart.rst @@ -0,0 +1,200 @@ +.. highlight:: sh + +.. _maple-quickstart: + +======================== + Maple Quickstart Guide +======================== + +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": + +.. image:: /_static/img/blinky-to-flash.png + :align: center + :alt: Upload to FLASH + +.. note:: + + You have the option between RAM and FLASH programming: FLASH saves + the program into permanent memory so the program will be run every + time the Maple is reset, while RAM simply injects the compiled + program into the processor's memory. + + Programming to RAM is faster to upload and a buggy program can be + wiped away with a simple reset, while FLASH memory is larger and is + the only option for permanently uploading a program. + +.. image:: /_static/img/verify_button.png + :align: left + :alt: Verify button + +Now press the "verify" button (furthest to the left with a "play" +arrow) 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 (finally!) time to plug in your Maple. Use a mini-b cable, +making sure that the power source jumper is on the USB header first. +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: + +.. 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 Maple. + + .. 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" + +The Maple should blink a short pattern on the blue status LED every +time it is plugged in, reset, or reprogrammed, just to let you know +it's there. If it ever starts throbbing in a slow, smooth pattern, +then you've got a problem: see the :ref:`troubleshooting +<troubleshooting>` page for help. + +If all systems are go, select the Board type and Serial Port +(something like :file:`COM3`, :file:`/dev/ttyACM0`, or +:file:`/dev/tty.usbmodemfa221`, depending on your platform, from the +Tools menu: + +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 to the +Maple. + +.. 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 blinky patterns on the Maple, and then a +constant blinking on and off. + +Go ahead and modify the file a little bit: if you change the +'delay(1000);' numbers to a different value the speed of the blink +will change. The value 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 Maple +back to the IDE over the USB connection. From the File menu, select +Examples > Stubs > HelloWorld (similarly to when you selected the +Blink program), and make sure the correct board and serial port +targets are selected from the Tools pull-down. + +Open the serial monitor window (button on the far right) and make sure +the 9600 baud speed is selected. Then go back to the code editing +window and upload your program (Upload will recompile your code +automatically if there's been any change since the last Verify). 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:`jtag`, and :command:`gcc`. + +Let us know what you come up with! Tag us with #leaflabs on Twitter, +post in the `forum`_, 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..2823947 --- /dev/null +++ b/docs/source/prolog.rst @@ -0,0 +1,7 @@ +.. 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` +.. |i2c| replace:: I\ :sup:`2`\ C diff --git a/docs/source/pwm.rst b/docs/source/pwm.rst new file mode 100644 index 0000000..1a8f4df --- /dev/null +++ b/docs/source/pwm.rst @@ -0,0 +1,118 @@ +.. _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 +-------- + +The Maple has a large number of 16-bit PWM outputs, each 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. + +Note that unlike the Arduino, the Maple does not have PWM +functionality on pin D10; all other pins are :ref:`compatible +<compatibility>`. + +The following table shows which timer can generate which PWM +outputs. See the :ref:`pin mapping table <pin-mapping-mega-table>` to +track down exactly which timer *channel* corresponds to each pin. + +.. _pwm-timer-table: + +.. csv-table:: + :header: Timer, PWM Headers + :delim: | + + Timer1 | D6,D7,D8 + Timer2 | D0,D1,D2,D3 + Timer3 | D11,D12,D27,D28 + Timer4 | D5,D9,D14,D24 + +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.arcfn.com/2009/07/secrets-of-arduino-pwm.html>`_ at Non-Lexical Vocables +* STMicro documentation for STM32F103RB microcontroller: + + * `Datasheet <http://www.st.com/stonline/products/literature/ds/13587.pdf>`_ (pdf) + * `Reference Manual <http://www.st.com/stonline/products/literature/rm/13902.pdf>`_ (pdf) diff --git a/docs/source/specs.rst b/docs/source/specs.rst new file mode 100644 index 0000000..4972a83 --- /dev/null +++ b/docs/source/specs.rst @@ -0,0 +1,29 @@ +.. _specs: + +.. _specs-Technical-Specifications: + +================================ +Maple's Technical Specifications +================================ + + * STM32 F103RB: a **32-bit** ARM Cortex M3 microprocessor + * Clock Speed: **72 MHz** + * Operating Voltage: 3.3V + * Input Voltage (recommended): 3.0V-12V + * 39 Digital I/O Pins (:ref:`GPIO <gpio>`) + * 16 Analog Input Pins + * 12-bit **ADC** resolution (:ref:`ADC <adc>`) + * 15 **PWM** pins at 16-bit resolution (:ref:`PWM <pwm>`) + * Dedicated **USB** port for programming and communications (:ref:`USB<usb>`) + * External **JTAG** interface (:ref:`USB <jtag>`) + * **128 Flash** and **20KB SRAM** + * 64 Channel nested vector interrupt handler (including external interrupt on GPIO’s) + * Integrated **SPI** (:ref:`SPI<spi>`) + * Integrated **I2C** (:ref:`I2C<i2c>`) + * 7 Channels of Direct Memory Access (DMA) + * 3 **USART** divices (:ref:`USART <usart>`) + * Four 4-channel Timers (:ref:`Timers <timers>`) + * Supplies up to 800mA @ 3.3v + * Support for low power and sleep modes (<500uA) + * Dimensions are 2.05″x2.1″ + diff --git a/docs/source/spi.rst b/docs/source/spi.rst new file mode 100644 index 0000000..ba43eef --- /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 Maple has two SPI ports. The first has NSS on D10, MOSI on +D11, MISO on D12, and SCK on D13. The second has NSS on D31, SCK on +D32, MISO on D33, and MOSI on D34. + +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://www.arduino.cc/playground/Code/Spi>`_ +* `Hardcore SPI on Arduino <http://klk64.com/arduino-spi/>`_ by kik64 +* STMicro documentation for STM32F103RB microcontroller: + + * `Datasheet <http://www.st.com/stonline/products/literature/ds/13587.pdf>`_ (pdf) + * `Reference Manual <http://www.st.com/stonline/products/literature/rm/13902.pdf>`_ (pdf) + diff --git a/docs/source/timers.rst b/docs/source/timers.rst new file mode 100644 index 0000000..56dd686 --- /dev/null +++ b/docs/source/timers.rst @@ -0,0 +1,206 @@ +.. 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. + +libmaple Reference +------------------ + +The libmaple API for interacting with timers is documented at the +:ref:`HardwareTimer reference <lang-hardwaretimer>`. + +Caveats +------- + +.. _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 the following table to match up timer +channels and Maple header pin numbers: + +.. _timers-pin-channel-map: + +.. csv-table:: + :header: Timer, Ch. 1 pin, Ch. 2 pin, Ch. 3 pin, Ch. 4 pin + + ``Timer1``, 6, 7, 8, -- + ``Timer2``, 2, 3, 1, 0 + ``Timer3``, 12, 11, 27, 28 + ``Timer4``, 5, 9, 14, 24 + +**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. + +.. compound:: + + **Jitter:** other interrupts (USB, Serial, SysTick, or other + timers) can and will get called before or during the timer + interrupt routines, causing pseudorandom delays and other + frustrations. + + Disabling the 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>`). + + Disabling SysTick with ``systick_disable()`` helps as well. + However, calling this function will break the ``micros()`` and + ``millis()`` functions. + +**General:** working with timers and interrupts can be tricky and hard +to debug; they are a somewhat "advanced" topic. Start simple, test +with :ref:`ASSERT() <language-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 (e.g. USB, +Serial, SysTick) if those other interrupts are important for your +program. + +SysTick Peripheral +------------------ + +The SysTick peripheral allows another, simple way to perform periodic +or delayed events. This separate timer does not conflict with any +other peripherals, but the associated 1kHz interrupt can jitter the +general purpose timer interrupts; this is clearly seen when running +VGA code, where the timing jitters are transformed into visual jags in +the image. The SysTick peripheral can be disabled by calling +``systick_disable()``, and re-enabled using ``systick_resume()``. + +Code Examples +------------- + +LED blink +^^^^^^^^^ + +:: + + #define LED_RATE 500000 // in microseconds; should give 0.5Hz toggles + + void handler_led(void); + + void setup() + { + // Set up the LED to blink + pinMode(BOARD_LED_PIN, OUTPUT); + + // Setup Timer + Timer2.setChannel1Mode(TIMER_OUTPUTCOMPARE); + Timer2.setPeriod(LED_RATE); // in microseconds + Timer2.setCompare1(1); // overflow might be small + Timer2.attachCompare1Interrupt(handler_led); + } + + void loop() { + // Nothing! It's all in the interrupts + } + + void handler_led(void) { + toggleLED(); + } + +Racing Counters +^^^^^^^^^^^^^^^ + +:: + + void handler_count1(void); + void handler_count2(void); + + int count1 = 0; + int count2 = 0; + + void setup() + { + // Set up BUT for input + pinMode(BOARD_BUTTON_PIN, INPUT_PULLUP); + + // Setup Counting Timers + Timer3.setChannel1Mode(TIMER_OUTPUTCOMPARE); + Timer4.setChannel1Mode(TIMER_OUTPUTCOMPARE); + Timer3.pause(); + Timer4.pause(); + Timer3.setCount(0); + Timer4.setCount(0); + Timer3.setOverflow(30000); + Timer4.setOverflow(30000); + Timer3.setCompare1(1000); // somewhere in the middle + Timer4.setCompare1(1000); + Timer3.attachCompare1Interrupt(handler1); + Timer4.attachCompare1Interrupt(handler2); + Timer3.resume(); + Timer4.resume(); + } + + void loop() { + // Display the running counts + SerialUSB.print("Count 1: "); + SerialUSB.print(count1); + SerialUSB.print("\t\tCount 2: "); + SerialUSB.println(count2); + + // Run... while BUT is held, pause Count2 + for(int i = 0; i<1000; i++) { + if(digitalRead(BOARD_BUTTON_PIN)) { + Timer4.pause(); + } else { + Timer4.resume(); + } + delay(1); + } + } + + void handler1(void) { + count1++; + } + void handler2(void) { + count2++; + } diff --git a/docs/source/troubleshooting.rst b/docs/source/troubleshooting.rst new file mode 100644 index 0000000..f3052d9 --- /dev/null +++ b/docs/source/troubleshooting.rst @@ -0,0 +1,236 @@ +.. highlight:: sh + +.. _troubleshooting: + +Troubleshooting +=============== + +This page documents common problems and their solutions. + +.. contents:: Contents + :local: + +=================== + Hardware problems +=================== + +The status LED is throbbing and I can't upload my program! +---------------------------------------------------------- + +The LED throbs when there has been a failed software :ref:`assertion +<language-assert>`. + +You can still reprogram by resetting the board and uploading during +the short window when the bootloader waits for a program. + +To make this window longer (it can be hard to get the timing right), +use :ref:`perpetual bootloader mode +<troubleshooting-perpetual-bootloader>`. + +My board is bricked! I can't upload via the bootloader no matter what! +---------------------------------------------------------------------- + +Use the hardcoded serial STM32 serial bootloader to :ref:`re-flash the +bootloader <bootloader-reflashing>`. + +If it 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:`compatibility <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 rev3 boards shipped in May-June 2010 may have had unreliable +buttons; see the :ref:`errata page <errata>` 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. + +.. TODO: remove when Python version is released + +``undefined reference to setup()/loop()`` +----------------------------------------- + +Your sketch/program either does not include one of the :ref:`setup() +<lang-setup>` or `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. + +.. TODO remove when the Python version is released + +.. _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 you don't have a Maple plugged in or powered on. +Try unplugging and plugging your Maple 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 Maples installed; how do I know which one will get flashed? +--------------------------------------------------------------------------- + +Because the Maple IDE uses DFU to upload programs, you can't select a +particular Maple from the Serial Port menu to upload to a particular +board. There's no solution to this problem for now: you'll have to +just plug in the Maples 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; :command:`make` isn't smart enough to rebuild everything that +needs to be for the new target. + +.. _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 Maple or uploading a new program. The operating +system doesn't like that, and locks up that device. After reset the +Maple 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 09.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 into perpetual bootloader mode: + +#. Plug your Maple into the USB port. + +#. 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. + +#. 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. + diff --git a/docs/source/unix-toolchain.rst b/docs/source/unix-toolchain.rst new file mode 100644 index 0000000..836f777 --- /dev/null +++ b/docs/source/unix-toolchain.rst @@ -0,0 +1,423 @@ +.. highlight:: sh + +.. _unix-toolchain: + +=========================== + Unix Toolchain Quickstart +=========================== + +This is a tutorial for using the Maple with a standard Unix toolchain. +It's not necessary to do this in order to program the Maple; you can +always :ref:`install the Maple IDE <maple-ide-install>` instead. + +You'll need a Maple board, a mini-b USB cable, a functional computer, +and root access to that computer. This guide assumes you've had +success with the IDE on your machine and that you are fairly +comfortable with the Unix command line; some previous experience with +editing your shell startup script (.bashrc, .tcshrc, etc.) and using +`make <http://www.gnu.org/software/make/>`_ is recommended. For +generic installation/setup issues, the :ref:`IDE installation +<maple-ide-install>` and :ref:`troubleshooting` pages may be +helpful. If all else fails, try our `forum`_, or `contact us +directly`_\ ! + +We currently have instructions for 32- and 64-bit Linux and OS X Snow +Leopard. If you're on another Unix platform, Windows, or an earlier +version of OS X, we're guessing that you can translate/port these +directions on your own. As a jumping off point, you might want to +begin with these `stripped down distributions +<http://static.leaflabs.com/pub/codesourcery/>`_ of the `CodeSourcery +GCC compiler tools <http://www.codesourcery.com/sgpp/features.html>`_ +(including Win32 versions). If you do have success on other platforms, +please post in the forums, so we can fold your tips into this +document! + +.. contents:: Contents + :local: + +.. _toolchain-linux-setup: + +Setup +----- + +Linux +^^^^^ + +These instructions are oriented towards Linux users using a +contemporary Debian-based distribution. + +**1. Collect and Install Tools** + +First I'll give the commands to run, then explain:: + + $ sudo aptitude install build-essential git-core wget screen dfu-util \ + openocd python python-serial + +You'll want to install a bunch of developer "basics" like +:command:`make`, :command:`tar`, etc. A good catch-all for these +tools is the "build-essential" meta-package on most Debian platforms: +installing this fake package will pull in dozens of useful tools +without bogging your system down too much. ``git-core`` is the name of +the git package; `Git <http://git-scm.com/>`_ is a distributed code +versioning system we use to track changes in our source +code. :command:`wget` is a simple tool to download files over http +from the command line, and is optional (you could pull in the required +downloads using a browser). :command:`screen` is a really cool virtual +terminal program; in the context of Maple, we use it to connect to +serial port devices. + +:command:`dfu-util` is a tool from the `OpenMoko`_ project that we use +to upload programs to the Maple over USB. + +.. _OpenMoko: http://openmoko.com/ + +:command:`openocd` is a `JTAG +<http://en.wikipedia.org/wiki/Joint_Test_Action_Group>`_ control +program used in conjunction with an ARM JTAG device to do in circuit +debugging (pause/resume program execution, upload and download code, +read out register status, etc). (optional) + +Lastly, 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 +<http://pyserial.sourceforge.net/>`_ library (the ``python-serial`` +package; this could also be installed with `easy_install +<http://peak.telecommunity.com/DevCenter/EasyInstall>`_). + +**2. Fetch libmaple and Compiler Toolchain** :: + + $ cd ~ + $ git clone git://github.com/leaflabs/libmaple.git libmaple + $ 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 # or wherever these tools ended up + +This step is fairly straightforward: do a git clone of the `libmaple +repository <http://github.com/leaflabs/libmaple>`_ to some directory, +then download and extract the ARM compiler toolchain. + +The :file:`arm/bin/` directory will need to be added to ``PATH``; you +can check that this worked by entering ``arm-none-`` and hitting tab +to auto-complete (bash should show a bunch of results). Regardless of +where you put the toolchain, make sure to preserve its internal +directory layout, as the binaries make relative path calls and +references. + +After you're done, you'll probably want to update your shell startup +script so :file:`~/libmaple/arm/bin` stays in your ``PATH``. + +.. _toolchain-udev: + +**3. Install udev Rules** + +From the libmaple directory, :: + + $ groups # make sure it includes plugdev; if not add, yourself to it + $ sudo cp support/scripts/45-maple.rules /etc/udev/rules.d/45-maple.rules + $ sudo /etc/init.d/udev restart + +As a security precaution on linux, unknown USB devices can only be +accessed by the superuser. This udev script identifies the Maple based +on its vendor and product IDs, mounts it to :file:`/dev/maple`, and +grants read/write permissions to the ``plugdev`` group. After +restarting :command:`udev` you'll need to fully unplug or power cycle +any Maples connected to the computer. + +**So far, so good?** + +Great! Test your setup by :ref:`compiling a sample program +<toolchain-test>`. + +.. _toolchain-osx-setup: + +OS X +^^^^ + +These instructions have been tested successfully on OS X 10.6.4. As +stated previously, this document assumes a general level of Unix +aptitude on the part of the reader; if you're uncomfortable using +Terminal (or if you don't know what that means), then you should +probably stick with using the `Maple IDE +<http://leaflabs.com/docs/maple-ide/>`_ to develop programs. + +**1. Collect and Install Tools** + +You will need the following tools\ [#fmacports]_ to get started: + + 1. `XCode <http://developer.apple.com/technologies/xcode.html>`_: If + you're reading this, you've probably already got this. Provides + compilers and other basic tools of the trade. It's a free download, + but requires registration (gross, we know). + + 2. `Git <http://git-scm.com/>`_: 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. + + 3. :command:`dfu-util`: A tool from `OpenMoko`_ that we use to upload + programs to the Maple over USB. If you're feeling masochistic, there + are instructions for `building dfu-util from source + <http://wiki.openmoko.org/wiki/Dfu-util#Mac>`_. + + However, if you've got better things to do, you can steal a dfu-util + binary from a program called `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 copy + the .app into your :file:`/Applications` folder (or wherever you + like). Let's pretend you saved the .app to the directory + + :file:`/Applications/OpenMoko Flasher.app` + + Then the :command:`dfu-util` binary resides in + + :file:`/Applications/OpenMoko Flasher.app/Contents/Mac OS/dfu-util` + + To get access to it from the command line, just 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:: + Just copying the binary somewhere doesn't work, as it relies on + dynamically linked libraries found elsewhere in the .app + bundle. It's possible to pull just the relevant pieces out of the + .app, but you're on your own. + + To make sure this worked, try plugging in your Maple, making sure + it's in bootloader mode (you can do this by pressing RESET, then + quickly pressing BUT and holding it for several seconds), then + running :: + + $ dfu-util -l + + If you see some lines that look like :: + + 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" + + then you're all set. + + 4. 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 + <http://pyserial.sourceforge.net/>`_ library. Download the `latest + version <http://pypi.python.org/pypi/pyserial>`_. After you download + and untar, install it with :: + + $ cd /path/to/pyserial-x.y + $ python setup.py build + $ sudo python setup.py install + + The package is also available via :command:`easy_install`, so if + you're comfortable using that, you could also install it with :: + + $ easy_install pyserial + +**2. Fetch libmaple and Compiler Toolchain** + +You first need to clone libmaple:: + + $ cd ~ + $ git clone git://github.com/leaflabs/libmaple.git libmaple + +Then you need to get the cross-compilers we use to build a +project. These are just modified versions of GCC; you can `download +them for OS X here +<http://static.leaflabs.com/pub/codesourcery/gcc-arm-none-eabi-latest-osx32.tar.gz>`_. Assuming +you saved this file to + + :file:`~/Downloads/gcc-blah-blah-osx32.tar.gz` + +you can then unpack the archive and let OS X know where the compilers +live with :: + + $ cd ~/Downloads + $ tar -xvzf gcc-blah-blah-macosx32.tar.gz + $ mv arm ~/libmaple/arm + $ export PATH=$PATH:~/libmaple/arm/bin + +After that's done, you'll probably want to update your shell startup +script so :file:`~/libmaple/arm/bin` stays in your ``PATH``. + +**So far, so good?** + +Great! Go on to the next section, where you test everything out. + +.. _toolchain-test: + +Test compilation +---------------- + +Get back into the libmaple directory (this tutorial assumes you put it +in :file:`~/libmaple`) and test that you've installed all the compilation +tools correctly:: + + $ cd ~/libmaple + $ cp main.cpp.example main.cpp + $ make clean + $ make + +If it all works out, you should end up seeing something like this:: + + find build -iname *.o | xargs arm-none-eabi-size -t + text data bss dec hex filename + 482 4 24 510 1fe build/wirish/comm/HardwareSerial.o + 260 0 0 260 104 build/wirish/comm/HardwareSPI.o + 60 0 0 60 3c build/wirish/wirish.o + + [...] + + 2196 0 1 2197 895 build/libmaple/usb/usb_lib/usb_core.o + 1904 0 0 1904 770 build/libmaple/usb/usb_lib/usb_regs.o + 56 0 0 56 38 build/libmaple/usb/usb_lib/usb_init.o + 344 0 0 344 158 build/libmaple/usb/usb_hardware.o + 6637 0 58 6695 1a27 build/main.o + 21499 201 391 22091 564b (TOTALS) + + Final Size: + arm-none-eabi-size build/maple.out + text data bss dec hex filename + 21824 200 552 22576 5830 build/maple.out + Flash build + +Woo! It worked. The ``dec`` field at the end gives the total program +size in bytes. The long listing of object files above the ``Final +Size`` helps to identify bloated code. As you write larger projects, +you may find that they use too much space. If that happens, the +file-by-file listing will help you track down the fatties porking up +your program. + +.. _toolchain-upload: + +Upload a program +---------------- + +Ok, let's blow away the little example program and upload the +interactive test session to your Maple. This will let you interact +textually with the Maple via USB-serial. If you're on Linux, then +before executing :command:`make install`, you'll want to have the udev +rules setup :ref:`as described above <toolchain-udev>`. Plug in your Maple +using the mini-b USB cable; then run :: + + $ cd ~/libmaple + $ 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, :command:`make clean`, etc. If nothing works, the `forum`_ is +your friend. + +.. _toolchain-serialusb: + +Communicate over USB-serial interface +------------------------------------- + +Okay, now that we've flashed the interactive test session to the +Maple, let's test it out. The device for the maple should look +something like :file:`/dev/ttyACMXXX` on Linux or +:file:`/dev/tty.usbmodemXXX` on OS X, but it might have a slightly +different name on your system. To open up a session, run :: + + $ screen /dev/ttyXXX + +If the interactive test program built and uploaded correctly, you +should be able to connect without any errors reported by +:command:`screen`. Type ``h`` or hit the space bar to get a response; +there are a number of commands which demonstrate Maple peripheral +features. As of October 2010, the HardwareSerial library is blocking, +so using any commands which would write to the USART Serial ports will +cause the program to hang. To exit the screen session, type :kbd:`C-a +C-\\` (control-a, followed by control-backslash) on Mac, or :kbd:`C-a +k` (control-a k) on Linux, and type ``y`` when prompted if you're +sure. + +.. note:: + + Using :command:`screen` in this way sometimes messes up your + terminal session on OS X. If your shell starts acting up after you + exit screen, you should be able to fix it with :: + + $ reset && clear + +.. _toolchain-projects: + +Starting your own projects +-------------------------- + +.. TODO fix the build-targets.mk mess, note the "library" target + +So everything worked, and you want to start your own project? Great! +It's easy. Just set the environment variable ``LIB_MAPLE_HOME`` in +your shell startup script to point to the libmaple repository you +cloned (this tutorial assumes you put it in :file:`~/libmaple`). For +example, if you use bash as your shell, just put this line in your +:file:`~/.bashrc` or :file:`~/.bash_profile`:: + + export LIB_MAPLE_HOME=~/libmaple + +Now, in order to start your own projects, just grab a copy of the +:file:`Makefile` and skeleton :file:`main.cpp` we provided in the +libmaple repository, and you're good to go:: + + $ cd + $ mkdir my-awesome-project + $ cp ~/libmaple/Makefile ~/libmaple/build-targets.mk my-awesome-project + $ cp ~/libmaple/main.cpp.example my-awesome-project/main.cpp + +(TEMPORARY: The file :file:`build-targets.mk` is where the rule to +build the object file for :file:`main.cpp` lives. If you have multiple +source files, you'll probably need to look at it and edit as +appropriate. We're sorry about that and will update the Makefile +structure later to remove this pain point.) Then hack away! You can +:command:`make`, :command:`make clean`, and :command:`make install` +from your new directory :file:`my-awesome-project` just like you did +in the libmaple repository. + +.. note:: + + We update the libmaple repository 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 $LIB_MAPLE_HOME + $ git pull + + The `commits page + <http://github.com/leaflabs/libmaple/commits/master>`_ for the + github repository is a good place to watch for bleeding-edge + updates; our `blog <http://leaflabs.com/blog/>`_ is the place to + watch for major releases. We keep releases of libmaple and the + Maple IDE in lockstep, so any IDE updates will have corresponding + library updates. + +.. _toolchain-openocd: + +Debug with OpenOCD +------------------ + +TODO. For now see `this great guide +<http://fun-tech.se/stm32/OpenOCD/index.php>`_ from fun-tech.se, and +the ``jtag`` Makefile target. + +.. _toolchain-exuberantly: + +Go forth exuberantly! +--------------------- + +Let us know what you come up with! Use #leaflabs on Twitter, post in +the `forum`_, track us down in the real world, whatever. We love +projects! + +.. rubric:: Footnotes + +.. [#fmacports] Some of these software packages might be available on + `MacPorts <http://www.macports.org/>`_. The author had some bad + experiences with MacPorts a few years ago, though, and hasn't + touched it since. Of course, your mileage may vary. diff --git a/docs/source/usart.rst b/docs/source/usart.rst new file mode 100644 index 0000000..3beb3fc --- /dev/null +++ b/docs/source/usart.rst @@ -0,0 +1,34 @@ +.. _usart: + +======= + USART +======= + +.. contents:: + :local: + +Hardware/Circuit Design +----------------------- + +The Maple has 3 separate USART devices. In the most simple use case, +the RX and TX pins are used to send data at a predetermined baudrate +with the line voltage level relative to ground. Their usage is +documented in the :ref:`Serial Ports <lang-serial>` language reference +page. + +Compatible Devices and Specifications +------------------------------------- + +We have successfully used the Maple 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 reference on Serial <http://arduino.cc/en/Reference/Serial>`_ +* STMicro documentation for STM32F103RB microcontroller: + + * `Datasheet <http://www.st.com/stonline/products/literature/ds/13587.pdf>`_ (pdf) + * `Reference Manual <http://www.st.com/stonline/products/literature/rm/13902.pdf>`_ (pdf) diff --git a/docs/source/usb.rst b/docs/source/usb.rst new file mode 100644 index 0000000..f502f31 --- /dev/null +++ b/docs/source/usb.rst @@ -0,0 +1,45 @@ +.. highlight:: cpp + +.. _usb: + +===== + USB +===== + +The Maple STM32 microprocessor includes 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 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 as part of the auto-reset feature of the +IDE to program the board on Maple Rev 3 and Rev 5: a :ref:`magic +sequence of control line toggles and transmitted data +<bootloader-rev3>` causes the 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.htm>`_ overview from Beyond Logic +* `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>`_ +* STMicro documentation for STM32F103RB microcontroller: + + * `Datasheet <http://www.st.com/stonline/products/literature/ds/13587.pdf>`_ (pdf) + * `Reference Manual <http://www.st.com/stonline/products/literature/rm/13902.pdf>`_ (pdf) + * `Programming Manual <http://www.st.com/stonline/products/literature/pm/15491.pdf>`_ (pdf; assembly + language and register reference) |