diff options
62 files changed, 2670 insertions, 1084 deletions
@@ -7,3 +7,4 @@ TAGS *~ *.swp docs/doxygen/ +arm @@ -66,7 +66,10 @@ endif # Set all submodules here LIBMAPLE_MODULES := $(SRCROOT)/libmaple LIBMAPLE_MODULES += $(SRCROOT)/wirish +# Official libraries: LIBMAPLE_MODULES += $(SRCROOT)/libraries/Servo +LIBMAPLE_MODULES += $(SRCROOT)/libraries/LiquidCrystal +LIBMAPLE_MODULES += $(SRCROOT)/libraries/Wire # call each module rules.mk $(foreach m,$(LIBMAPLE_MODULES),$(eval $(call LIBMAPLE_MODULE_template,$(m)))) @@ -2,10 +2,11 @@ Quick TODO -------------------------------------------------------------------- - write language unit test - more maple-specific example programs +- maple mini serial bootloader HOWTO +- maple and mini jtag HOWTO Peripherals ------------------------------------------------------------------- -- complete timers and interrupt stuff - I2C wrap up - SPI wrap up @@ -16,9 +17,6 @@ EEPROM: uint8 read(int) void write(int, uint8) -Servo: - modify timer code, "banks" of pins corresponding to a timer - Firmata: edit Firmata.h for capabilities diff --git a/docs/flibbit.py b/docs/flibbit.py deleted file mode 100644 index 5f149d4..0000000 --- a/docs/flibbit.py +++ /dev/null @@ -1,26 +0,0 @@ -import os -import shutil -import re -from os.path import * - -src = '/Users/mbolivar/foo/arduino.cc/en/Reference' -dst = '/Users/mbolivar/hack/leaf/libmaple/docs/source/arduino' - -fs = [x for x in os.listdir(src) if x.endswith('.rst')] - -def process(line): - if re.match('-+$', line.rstrip()): - return '=' * (len(line) - 1) + '\n' - elif re.match('\^+$', line.rstrip()): - return '-' * (len(line) - 1) + '\n' - return line - -for f in fs: - print 'processing:', f - with open(join(src,f), 'r') as f_in: - with open(join(dst, basename(f)), 'w') as f_out: - label = '.. _arduino-%s:\n\n' % (f.split('.')[0]) - f_out.write(label) - for line in list(f_in.readlines())[20:-22]: - f_out.write(process(line)) - diff --git a/docs/source/_templates/layout.html b/docs/source/_templates/layout.html index bf05832..93547f0 100644 --- a/docs/source/_templates/layout.html +++ b/docs/source/_templates/layout.html @@ -1,6 +1,5 @@ {% extends "!layout.html" %} {% block rootrellink %} - <li><a href="http://leaflabs.com">LeafLabs</a> |</li> - <li><a href="index.html">Docs Home</a> |</li> + <li><a href="http://leaflabs.com/">LeafLabs</a> |</li> {{ super() }} {% endblock %} diff --git a/docs/source/errata.rst b/docs/source/errata.rst index a3bb66a..8feb6ea 100644 --- a/docs/source/errata.rst +++ b/docs/source/errata.rst @@ -10,22 +10,22 @@ 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 ----------- -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, among other changes: - -.. figure:: /_static/img/maple_rev5.png - :align: center - :alt: 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 @@ -43,13 +43,6 @@ Potential failure modes: Maple Rev 3 ----------- -This batch of boards went on sale beginning in May 2010. They have a -darker red silkscreen and the "infinity-leaf" logo: - -.. figure:: /_static/img/maple_rev3.png - :align: center - :alt: Maple Rev 3 - Known issues: * **Bad/Sticky Buttons**: a number of Rev 3 boards sold in May-June 2010 @@ -106,13 +99,6 @@ Potential failure modes: Maple Rev 1 ----------- -This batch of 100 boards shipped in later 2009. They have a red -silkscreen and the logo is a single pixelated leaf: - -.. figure:: /_static/img/maple_rev1.png - :align: center - :alt: Maple Rev 1 - Known issues: * **ADC noise**: generally very high, in particular when the USB port diff --git a/docs/source/external-interrupts.rst b/docs/source/external-interrupts.rst index 5187ca4..b2cbbb1 100644 --- a/docs/source/external-interrupts.rst +++ b/docs/source/external-interrupts.rst @@ -84,14 +84,8 @@ The following table shows which pins can be used on which lines. Function Reference ------------------ -.. doxygenfunction:: attachInterrupt - -.. doxygenfunction:: detachInterrupt - -.. doxygenenum:: ExtIntTriggerMode - -.. doxygentypedef:: voidFuncPtr - +- :ref:`attachInterrupt() <lang-attachinterrupt>` +- :ref:`detachInterrupt() <lang-detachinterrupt>` Code example ------------ 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/index.rst b/docs/source/index.rst index 825ec81..5c1718f 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -16,27 +16,26 @@ Have fun! **Usage Guides:** .. toctree:: - :maxdepth: 2 + :maxdepth: 1 Quickstart <maple-quickstart> IDE Installation <maple-ide-install> - IDE Anatomy <ide> + IDE Usage <ide> + Command-Line Toolchain <unix-toolchain> .. _index-maple-programming: **Maple Programming:** .. toctree:: - :maxdepth: 2 + :maxdepth: 1 - Maple Language<language> - Maple Libraries <libraries> + Language <language> + Libraries <libraries> Arduino Compatibility <compatibility> + libmaple <libmaple> External Interrupts <external-interrupts> - Command-Line Tools & APIs <libmaple> Bootloader <bootloader> - - Troubleshooting <troubleshooting> Known Problems <errata> @@ -47,15 +46,32 @@ Have fun! .. toctree:: :maxdepth: 1 - i2c - pwm + adc gpio - usb + i2c jtag - adc + pwm spi - usart 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: diff --git a/docs/source/lang/api/attachinterrupt.rst b/docs/source/lang/api/attachinterrupt.rst index 0b8907f..7c5a6c7 100644 --- a/docs/source/lang/api/attachinterrupt.rst +++ b/docs/source/lang/api/attachinterrupt.rst @@ -15,7 +15,28 @@ occurs. Library Documentation --------------------- -.. doxygenfunction:: attachInterrupt +.. 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 @@ -34,7 +55,6 @@ 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 ---------------- @@ -43,7 +63,6 @@ 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 @@ -55,7 +74,6 @@ sensor that is trying to catch a click, or an infrared slot sensor situations, using an interrupt can free the microcontroller to get some other work done while not missing the doorbell. - Example ------- @@ -78,7 +96,6 @@ Example state = !state; } - Arduino Compatibility --------------------- @@ -89,14 +106,10 @@ additional four: numbers 2 (pin 21), 3 (pin 20), 4 (pin 19), and 5 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/constants.rst b/docs/source/lang/api/constants.rst index 4426293..72738b8 100644 --- a/docs/source/lang/api/constants.rst +++ b/docs/source/lang/api/constants.rst @@ -242,10 +242,18 @@ type, follow it with: 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>`. + 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>`. + :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: @@ -321,6 +329,8 @@ See Also - :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>` diff --git a/docs/source/lang/api/detachinterrupt.rst b/docs/source/lang/api/detachinterrupt.rst index adb2439..41642a7 100644 --- a/docs/source/lang/api/detachinterrupt.rst +++ b/docs/source/lang/api/detachinterrupt.rst @@ -6,11 +6,20 @@ detachInterrupt() Used to disable an interrupt specified with :ref:`lang-attachinterrupt`\ . - Library Documentation --------------------- -.. doxygenfunction:: detachInterrupt +.. 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 --------------------- @@ -31,7 +40,4 @@ See Also - :ref:`attachInterrupt() <lang-attachInterrupt>` - - - .. include:: cc-attribution.txt diff --git a/docs/source/lang/api/hardwaretimer.rst b/docs/source/lang/api/hardwaretimer.rst index 258471b..3e5424c 100644 --- a/docs/source/lang/api/hardwaretimer.rst +++ b/docs/source/lang/api/hardwaretimer.rst @@ -317,6 +317,8 @@ For example, to set the prescale factor on timer 1 to 5, call 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. diff --git a/docs/source/lang/api/millis.rst b/docs/source/lang/api/millis.rst index 54e4507..0288c56 100644 --- a/docs/source/lang/api/millis.rst +++ b/docs/source/lang/api/millis.rst @@ -40,7 +40,7 @@ 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:`ints <lang-int>`. +with other data types, such as :ref:`chars <lang-char>`. See Also -------- diff --git a/docs/source/lang/api/pwmwrite.rst b/docs/source/lang/api/pwmwrite.rst index 2c858ab..9d50077 100644 --- a/docs/source/lang/api/pwmwrite.rst +++ b/docs/source/lang/api/pwmwrite.rst @@ -33,21 +33,20 @@ Sets the output to the LED proportional to the value read from the potentiometer:: int analogPin = 3; // potentiometer connected to analog pin 3 - int val = 0; // variable to store the read value void setup() { pinMode(BOARD_LED_PIN, OUTPUT); // sets the LED pin as output - pinMode(analogPin, PWM); // sets the potentiometer pin as PWM - // output + pinMode(analogPin, INPUT_ANALOG); // sets the potentiometer pin as + // analog input } void loop() { - val = analogRead(analogPin); // read the input pin + int val = analogRead(analogPin); // read the input pin - analogWrite(BOARD_LED_PIN, val / 16); // analogRead values go from 0 - // to 4095, analogWrite values - // from 0 to 65535 + pwmWrite(BOARD_LED_PIN, val * 16); // analogRead values go from 0 + // to 4095, pwmWrite values + // from 0 to 65535, so scale roughly } See Also diff --git a/docs/source/lang/api/random.rst b/docs/source/lang/api/random.rst index f2a9762..dd8871d 100644 --- a/docs/source/lang/api/random.rst +++ b/docs/source/lang/api/random.rst @@ -7,13 +7,13 @@ random() The ``random()`` function generates pseudo-random numbers. -.. TODO keep tracking Sphinx/Breathe's ability to reference overloaded -.. functions so we can use doxygenfunction instead of manually -.. documenting this. - 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)``. diff --git a/docs/source/lang/cpp/arithmetic.rst b/docs/source/lang/cpp/arithmetic.rst index 91fe22e..7e8c3fc 100644 --- a/docs/source/lang/cpp/arithmetic.rst +++ b/docs/source/lang/cpp/arithmetic.rst @@ -97,7 +97,7 @@ 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 +ranges of integer datatypes on the Maple (the ranges of ``long long`` types are approximate): .. _lang-arithmetic-int-sizes: diff --git a/docs/source/lang/cpp/assignment.rst b/docs/source/lang/cpp/assignment.rst index b6ad4d5..f9430b4 100644 --- a/docs/source/lang/cpp/assignment.rst +++ b/docs/source/lang/cpp/assignment.rst @@ -15,47 +15,38 @@ 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 - senVal = analogRead(0); // store the (digitized) input voltage at analog pin 0 in 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 ) +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. - +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 -------- - -- `if (comparison operators) <http://arduino.cc/en/Reference/If>`_ -- `char <http://arduino.cc/en/Reference/Char>`_ -- `int <http://arduino.cc/en/Reference/Int>`_ -- `long <http://arduino.cc/en/Reference/Long>`_ - +- :ref:`if <lang-if>` +- :ref:`char <lang-char>` +- :ref:`int <lang-int>` +- :ref:`long long <lang-longlong>` .. rubric:: Footnotes @@ -66,5 +57,4 @@ See Also <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/built-in-types.rst b/docs/source/lang/cpp/built-in-types.rst index 1323db8..a7349e6 100644 --- a/docs/source/lang/cpp/built-in-types.rst +++ b/docs/source/lang/cpp/built-in-types.rst @@ -33,7 +33,7 @@ Integral types .. cpp:type:: long - 64-bit integer value. + 32-bit integer value. .. cpp:type:: long long diff --git a/docs/source/lang/cpp/compoundbitwise.rst b/docs/source/lang/cpp/compoundbitwise.rst index a4bbb24..8231130 100644 --- a/docs/source/lang/cpp/compoundbitwise.rst +++ b/docs/source/lang/cpp/compoundbitwise.rst @@ -31,8 +31,8 @@ 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``, ``long``, ``char``, ``byte``, etc.). You can use either an -integer variable or any :ref:`integer value +``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 @@ -115,9 +115,9 @@ 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``, ``long``, ``char``, ``byte``, 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 +``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 @@ -178,12 +178,11 @@ 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``, ``long``, ``char``, ``byte``, etc.). You can use either an +``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). +<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, ``^``:: diff --git a/docs/source/lang/cpp/doublecast.rst b/docs/source/lang/cpp/doublecast.rst index 511fe24..16a9907 100644 --- a/docs/source/lang/cpp/doublecast.rst +++ b/docs/source/lang/cpp/doublecast.rst @@ -12,7 +12,7 @@ data type. Here is an example:: 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``), you will get strange results. +(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. diff --git a/docs/source/lang/cpp/enum.rst b/docs/source/lang/cpp/enum.rst index ba82383..b6409eb 100644 --- a/docs/source/lang/cpp/enum.rst +++ b/docs/source/lang/cpp/enum.rst @@ -18,8 +18,7 @@ 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>` -or a :ref:`long <lang-long>`:: +``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; diff --git a/docs/source/lang/cpp/int.rst b/docs/source/lang/cpp/int.rst index ca75f75..3e96b69 100644 --- a/docs/source/lang/cpp/int.rst +++ b/docs/source/lang/cpp/int.rst @@ -24,6 +24,10 @@ arithmetic operations work mostly as you'd expect. There can be an 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:: @@ -56,8 +60,8 @@ See Also - :ref:`unsigned int <lang-unsignedint>` - :ref:`char <lang-char>` - :ref:`unsigned char <lang-unsignedchar>` -- :ref:`long <lang-long>` -- :ref:`unsigned long <lang-unsignedlong>` +- :ref:`long long <lang-longlong>` +- :ref:`unsigned long long <lang-unsignedlonglong>` - :ref:`Integer Constants <lang-constants-integers>` - :ref:`Variables <lang-variables>` diff --git a/docs/source/lang/cpp/keywords.rst b/docs/source/lang/cpp/keywords.rst index e3bc20d..f21cd0d 100644 --- a/docs/source/lang/cpp/keywords.rst +++ b/docs/source/lang/cpp/keywords.rst @@ -89,11 +89,11 @@ Types The following keywords are used for built-in types. - :ref:`bool <lang-booleanvariables>` -- :ref:`lang-char` -- :ref:`lang-double` -- :ref:`lang-float` -- :ref:`lang-int` -- :ref:`lang-long` +- :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) @@ -109,8 +109,7 @@ Qualifiers 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:`lang-unsignedlong`. + Examples: :ref:`lang-unsignedint`, :ref:`lang-unsignedchar`. - :ref:`volatile <lang-volatile>` is useful when declaring variables that may be modified by external interrupts. diff --git a/docs/source/lang/cpp/long.rst b/docs/source/lang/cpp/long.rst deleted file mode 100644 index d8498c0..0000000 --- a/docs/source/lang/cpp/long.rst +++ /dev/null @@ -1,52 +0,0 @@ -.. highlight:: cpp - -.. _lang-long: - -``long`` -======== - -The ``long`` data type stores extended size integer values. You can -use a ``long`` when your values are too large to fit into an :ref:`int -<lang-int>`. A ``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`` 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`` it is subject to the same :ref:`overflow issues -<lang-variables-rollover>` as any numeric data type. - -Here's an example of declaring a long (see :ref:`integer constants -<lang-constants-integers-u-l>` for an explanation of the "L" at the end of the -number):: - - // Speed of light in nanometers per second (approximate). - long c = 299792458000000000L; - -The general syntax for declaring an ``long`` variable named ``var``, -then giving it value ``val``, looks like:: - - long var = val; - -This is identical to the ``int`` syntax, with ``long`` replacing -``int``. - -Note that ``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`` instead of an ``int`` (besides the -extra storage) is that :ref:`arithmetic <lang-arithmetic>` operations -on ``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 <lang-unsignedlong>` -- :ref:`Integer Constants <lang-constants-integers>` -- :ref:`Variables <lang-variables>` - -.. include:: cc-attribution.txt diff --git a/docs/source/lang/cpp/longcast.rst b/docs/source/lang/cpp/longcast.rst index 2b92345..f588fc6 100644 --- a/docs/source/lang/cpp/longcast.rst +++ b/docs/source/lang/cpp/longcast.rst @@ -21,7 +21,7 @@ precision and limitations of ``long`` variables on the Maple. See Also -------- -- :ref:`long <lang-long>` - +- :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/return.rst b/docs/source/lang/cpp/return.rst index 7b5039e..b4ef5fd 100644 --- a/docs/source/lang/cpp/return.rst +++ b/docs/source/lang/cpp/return.rst @@ -21,7 +21,7 @@ Syntax: 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 ``long``, etc.; see :ref:`this note +``int`` to a ``double``, etc.; see :ref:`this note <lang-arithmetic-typeconversion>` for some references). Examples: diff --git a/docs/source/lang/cpp/unsignedint.rst b/docs/source/lang/cpp/unsignedint.rst index f6311da..ad3e2f2 100644 --- a/docs/source/lang/cpp/unsignedint.rst +++ b/docs/source/lang/cpp/unsignedint.rst @@ -31,6 +31,10 @@ that an ``unsigned int`` will "underflow" at 0, and "overflow" at 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:: @@ -47,8 +51,8 @@ See Also - :ref:`int <lang-int>` - :ref:`char <lang-char>` - :ref:`unsigned char <lang-unsignedchar>` -- :ref:`long <lang-long>` -- :ref:`unsigned long <lang-unsignedlong>` +- :ref:`long long <lang-longlong>` +- :ref:`unsigned long long <lang-unsignedlonglong>` - :ref:`Integer Constants <lang-constants-integers>` - :ref:`Variables <lang-variables>` diff --git a/docs/source/lang/cpp/unsignedlong.rst b/docs/source/lang/cpp/unsignedlong.rst deleted file mode 100644 index 14a4fc3..0000000 --- a/docs/source/lang/cpp/unsignedlong.rst +++ /dev/null @@ -1,41 +0,0 @@ -.. highlight:: cpp - -.. _lang-unsignedlong: - -``unsigned long`` -================= - -An unsigned version of the :ref:`long <lang-long>` data type. An -``unsigned 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). - -Like an :ref:`unsigned int <lang-unsignedint>`, an ``unsigned 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`` 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 "L" -at the end of the number):: - - // Speed of light in nanometers per second (approximate). - unsigned long c = 299792458000000000L; - -The general syntax for declaring an ``unsigned long`` variable named -``var``, then giving it value ``val``, looks like:: - - unsigned long var = val; - -See Also --------- - -- :ref:`long <lang-long>` -- :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/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 index e6da0c9..336d5ab 100644 --- a/docs/source/lang/cpp/variables.rst +++ b/docs/source/lang/cpp/variables.rst @@ -44,7 +44,7 @@ Here are a few examples of declaring variables of different types:: int lightSensVal; char currentLetter; - unsigned long speedOfLight = 186000UL; + unsigned long long speedOfLight = 186000ULL; char errorMessage = {"choose another option"}; // see string Naming Variables diff --git a/docs/source/language.rst b/docs/source/language.rst index 018eb8c..2ebe03c 100644 --- a/docs/source/language.rst +++ b/docs/source/language.rst @@ -102,59 +102,59 @@ A more exhaustive index is available at the :ref:`language-index`. | |* :ref:`unsigned int <lang-unsignedint>` | | |* :ref:`#include <lang-include>` | (4 bytes) |* :ref:`micros() <lang-micros>` | | | | | -| |* :ref:`long <lang-long>` (8 bytes) |* :ref:`delay() <lang-delay>` | -|**Arithmetic Operators** | | | -| |* :ref:`unsigned long <lang-unsignedlong>` |* :ref:`delayMicroseconds() | -|* :ref:`= <lang-assignment>` | (8 bytes) | <lang-delaymicroseconds>` | -| (assignment operator) | | | -| |* :ref:`float <lang-float>` (4 bytes) | | -|* :ref:`+ <lang-arithmetic>` (addition) | |**Math** | -| |* :ref:`double <lang-double>` (8 bytes) | | -|* :ref:`- <lang-arithmetic>` | |* :ref:`min() <lang-min>` | -| (subtraction) |* :ref:`Strings <lang-string>` | | +| |* ``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:`Arrays <lang-array>` | | +|* :ref:`* <lang-arithmetic>` |* :ref:`float <lang-float>` (4 bytes) | | | (multiplication) | |* :ref:`abs() <lang-abs>` | -| |* :ref:`enum <lang-enum>` | | +| |* :ref:`double <lang-double>` (8 bytes) | | |* :ref:`/ <lang-arithmetic>` (division) | |* :ref:`constrain() <lang-constrain>` | -| |* :ref:`Numeric types <lang-built-in-types>` | | +| |* :ref:`strings <lang-string>` | | |* :ref:`% <lang-modulo>` (modulo) | |* :ref:`map() <lang-map>` | -| |**Conversion** | | +| |* :ref:`arrays <lang-array>` | | | | |* :ref:`pow() <lang-pow>` | -|**Comparison Operators** |* :ref:`char() <lang-charcast>` | | +|**Comparison Operators** |* :ref:`enum <lang-enum>` | | | | |* :ref:`sqrt() <lang-sqrt>` | -|* :ref:`== <lang-comparison>` (equal to) |* :ref:`byte() <lang-bytecast>` | | +|* :ref:`== <lang-comparison>` (equal to) |* :ref:`numeric types <lang-built-in-types>` | | | | | | -|* :ref:`\!= <lang-comparison>` |* :ref:`int() <lang-intcast>` |**Trigonometry** | +|* :ref:`\!= <lang-comparison>` |**Conversion** |**Trigonometry** | | (not equal to) | | | -| |* :ref:`long() <lang-longcast>` |* :ref:`sin() <lang-sin>` | +| |* :ref:`char() <lang-charcast>` |* :ref:`sin() <lang-sin>` | |* :ref:`< <lang-comparison>` (less than) | | | -| |* :ref:`float() <lang-floatcast>` |* :ref:`cos() <lang-cos>` | +| |* :ref:`byte() <lang-bytecast>` |* :ref:`cos() <lang-cos>` | |* :ref:`> <lang-comparison>` | | | -| (greater than) |* :ref:`double() <lang-doublecast>` |* :ref:`tan() <lang-tan>` | +| (greater than) |* :ref:`int() <lang-intcast>` |* :ref:`tan() <lang-tan>` | | | | | -|* :ref:`<= <lang-comparison>` | | | -| (less than or equal to) |**Variable Scope & Qualifiers** |**Random Numbers** | -| | | | -|* :ref:`>= <lang-comparison>` |* :ref:`variables <lang-variables>`, |* :ref:`randomSeed() <lang-randomseed>` | -| (greater than or equal to) | :ref:`scope <lang-variables-scope>` | | +|* :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>` | -| |* :ref:`static <lang-static>` | | -|**Boolean Operators** | | | -| |* :ref:`volatile <lang-volatile>` |**Bits and Bytes** | -|* :ref:`&& <lang-boolean-and>` (and) | | | -| |* :ref:`const <lang-const>` |* :ref:`lowByte() <lang-lowbyte>` | -|* :ref:`|| <lang-boolean-or>` (or) | | | -| | |* :ref:`highByte() <lang-highbyte>` is | -|* :ref:`\! <lang-boolean-not>` (not) |**Utilities** | provided, though its use is discouraged. | | | | | -| |* :ref:`sizeof() <lang-sizeof>` |* :ref:`bitRead() <lang-bitread>` | -|**Pointer Operators** | | | +|**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>` | |* :ref:`bitSet() <lang-bitset>` | +| <lang-pointer>` |**Utilities** |* :ref:`bitSet() <lang-bitset>` | | | | | -|* :ref:`& reference operator | |* :ref:`bitClear() <lang-bitclear>` | +|* :ref:`& reference operator |* :ref:`sizeof() <lang-sizeof>` |* :ref:`bitClear() <lang-bitclear>` | | <lang-pointer>` | | | | | |* :ref:`bit() <lang-bit>` | | | | | diff --git a/docs/source/libmaple.rst b/docs/source/libmaple.rst index b76c7c8..8cc39a3 100644 --- a/docs/source/libmaple.rst +++ b/docs/source/libmaple.rst @@ -2,8 +2,8 @@ .. _libmaple: -``libmaple`` Reference -====================== +``libmaple`` +============ .. image:: /_static/img/libmaple-screenshot-small.png :align: center @@ -35,7 +35,6 @@ wrappers and code to imitate the Arduino programming library. .. toctree:: :maxdepth: 2 - Unix Toolchain Quickstart <unix-toolchain> Guide to using GCC's ARM target <arm-gcc> .. TODO LATER create, style, and host a pure Doxygen libmaple diff --git a/docs/source/maple-ide-install.rst b/docs/source/maple-ide-install.rst index ce50c49..92d1a96 100644 --- a/docs/source/maple-ide-install.rst +++ b/docs/source/maple-ide-install.rst @@ -61,6 +61,13 @@ 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. diff --git a/docs/source/maple-quickstart.rst b/docs/source/maple-quickstart.rst index ca902f3..08fa5c1 100644 --- a/docs/source/maple-quickstart.rst +++ b/docs/source/maple-quickstart.rst @@ -6,7 +6,7 @@ Maple Quickstart Guide ======================== -You'll need a `Maple board <http://leaflabs.com/store/>`_, a `mini-b +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. diff --git a/docs/source/unix-toolchain.rst b/docs/source/unix-toolchain.rst index e6039a2..836f777 100644 --- a/docs/source/unix-toolchain.rst +++ b/docs/source/unix-toolchain.rst @@ -8,7 +8,7 @@ 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 use our `IDE <maple-ide-install>`_ instead. +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 @@ -16,10 +16,10 @@ 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 `IDE install -<http://leaflabs.com/docs/libmaple/install/>`_ and -:ref:`troubleshooting` pages may be helpful. If all else fails, try -our `forum`_, or `contact us directly`_\ ! +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 @@ -28,7 +28,7 @@ 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, +(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! @@ -55,7 +55,7 @@ First I'll give the commands to run, then explain:: 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: +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 @@ -90,7 +90,7 @@ package; this could also be installed with `easy_install $ 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 arm-*-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 @@ -104,6 +104,9 @@ 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** @@ -136,15 +139,11 @@ 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. 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. +<http://leaflabs.com/docs/maple-ide/>`_ to develop programs. **1. Collect and Install Tools** -You will need the following tools to get started: +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 @@ -326,7 +325,7 @@ 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/tty-whatever-it-is + $ screen /dev/ttyXXX If the interactive test program built and uploaded correctly, you should be able to connect without any errors reported by @@ -335,20 +334,25 @@ 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), and type ``y`` when -prompted if you're sure. +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. -Using :command:`screen` in this way sometimes messes up your session. -If your shell starts acting up after you exit screen, you should be -able to fix it with :: +.. note:: - $ reset && clear + 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 @@ -402,87 +406,6 @@ 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-codeblocks: - -Do it all with Code::Blocks ---------------------------- - -.. TODO this really should reflect the new, more pleasant build system - -Optional. `Code::Blocks <http://www.codeblocks.org/>`_ is a generic -cross platform IDE. We don't personally use it for development, so we -haven't worked out all the kinks (e.g., debugging isn't integrated), -but it might be helpful for people who are allergic to `vim -<http://www.vim.org/>`_ and/or `Emacs -<http://www.gnu.org/software/emacs/>`_. The simple configuration -described here just calls down to the :file:`Makefile`, so follow the -above directions to get the command line tools configured (you'll -definitely need the arm-none-eabi-* tools on your ``PATH``), then -`install Code::Blocks <http://www.codeblocks.org/downloads/26>`_. You -can do this on Linux with:: - - $ sudo aptitude install codeblocks - -The first time it runs you'll maybe want to disable all the glitzy -"Getting Started" crap (when will they learn?). We've added a .cbp -"projects" file to the libmaple repository: you can try using that one -by copying it from :file:`support/codeblocks/libmaple.cbp` to the top -level directory, but no promises (it might be missing new source files -etc). It's probably worth reading through these instructions as well -to get a feel for how it all works. - -To create your own "libmaple" project, start with an "Empty Project" -with the "Folder to create project in" set to your -``LIB_MAPLE_HOME``. Make sure that the "Resulting filename" is in the -top level directory as well. - -.. image:: /_static/img/codeblocks_newproject.png - :align: center - :alt: Code::Blocks new project wizard - -Select the "GNU GCC Compiler" (it won't be used, anyway) and disable -the "Debug" configuration in the next window. Now you should have a -project with no files; add files by right clicking on the project in -the left panel file hierarchy and "Add files recursively". Import both -the :file:`wirish` and :file:`libmaple` directories recursively, then -add :file:`main.cpp` separately. - -.. image:: /_static/img/codeblocks_makefile.png - :align: center - :alt: Code::Blocks targets options - -Next we have to configure the Makefile targets. Go to the -"Properties..." menu under "Project" and check the "This is a custom -Makefile" box. Then go to the "Build targets" tab and create "ram" and -"flash" targets, both of type "Console application" and without the -Auto-generated filename prefixes or extensions. Set the Output -filename to :file:`support/codeblocks/program_flash.sh` and -:file:`support/codeblocks/program_ram.sh` respectively; these scripts -just call the program_ram/program_flash make targets and are a hack to -get the "run" button to upload code to the Maple. The IDE will warn -that these files will be overwritten, but they won't be. For both the -"flash" and "ram" targets, click the "Build options..." button (below -"Virtual targets..." etc) and go to the far right tab ("'Make' -commands"). Edit the Clean project/target line so it's just "clean" -(not "clean$target"), and set the "Build project/target" and "Compile -single file" commands to ``$make -f $makefile MAPLE_TARGET=$target`` -and ``$make -f $makefile MAPLE_TARGET=$target $file``, respectively. - -.. image:: /_static/img/codeblocks_maketargets.png - :align: center - :alt: Code::Blocks make targets - -Save all these changes, go back to the main IDE window, and try to -build/run. "Build" will compile everything, "Run" will run the upload -script in a terminal window (if there are problems they will flash by -very quickly; you can start Code::Blocks in a terminal window and -check the output in that base window if necessary), and "Rebuild" will -clean before rebuilding. - -.. image:: /_static/img/codeblocks_build.png - :align: center - :alt: Success! - .. _toolchain-exuberantly: Go forth exuberantly! @@ -491,3 +414,10 @@ 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/examples/blinky.cpp b/examples/blinky.cpp index 45c4528..5611987 100644 --- a/examples/blinky.cpp +++ b/examples/blinky.cpp @@ -2,16 +2,19 @@ #include "wirish.h"
-#define TEST_PIN 13
+// Use the pin attached to the built-in LED
+#define PIN BOARD_LED_PIN
void setup() {
- pinMode(TEST_PIN, OUTPUT);
+ pinMode(PIN, OUTPUT);
}
int toggle = 1;
void loop() {
- digitalWrite(TEST_PIN, toggle);
+ // You could just use toggleLED() instead, but this illustrates
+ // the use of digitalWrite():
+ digitalWrite(PIN, toggle);
toggle ^= 1;
delay(100);
}
@@ -22,8 +25,7 @@ void loop() { init();
}
-int main(void)
-{
+int main(void) {
setup();
while (1) {
diff --git a/examples/test-session.cpp b/examples/test-session.cpp index bfc1e58..845547d 100644 --- a/examples/test-session.cpp +++ b/examples/test-session.cpp @@ -7,46 +7,79 @@ #include "wirish.h" -#define LED_PIN 13 -#define PWM_PIN 2 +#define LED_PIN BOARD_LED_PIN +#define PWM_PIN 3 // choose your weapon #define COMM SerialUSB //#define COMM Serial2 +//#define COMM Serial3 + + +#define ESC ((uint8)27) -uint8 input = 0; -uint8 tiddle = 0; -int toggle = 0; int rate = 0; -int sample = 0; -// read these off maple board rev3 -// note that 38 is just a button and 39+ aren't functional as of 04/22/2010 -const uint8 pwm_pins[] = {0,1,2,3,5,6,7,8,9,11,12,14,24,25,27,28}; -const uint8 adc_pins[] = {0,1,2,10,11,12,13,15,16,17,18,19,20,27,28}; -#define NUM_GPIO 44 // 44 is the MAX -uint8 gpio_state[NUM_GPIO]; +#if defined(BOARD_maple) +const uint8 pwm_pins[] = + {0, 1, 2, 3, 5, 6, 7, 8, 9, 11, 12, 14, 24, 25, 27, 28}; +const uint8 adc_pins[] = + {0, 1, 2, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20, 27, 28}; + +#elif defined(BOARD_maple_mini) +const uint8 pwm_pins[] = {3, 4, 5, 8, 9, 10, 11, 15, 16, 25, 26, 27}; +const uint8 adc_pins[] = {3, 4, 5, 6, 7, 8, 9, 10, 11, 33}; // NB: 33 is LED + +#elif defined(BOARD_maple_native) +const uint8 pwm_pins[] = {12, 13, 14, 15, 22, 23, 24, 25, 37, 38, 45, + 46, 47, 48, 49, 50, 53, 54}; +const uint8 adc_pins[] = {6, 7, 8, 9, 10, 11, + /* the following are on ADC3, which lacks support: + 39, 40, 41, 42, 43, 45, */ + 46, 47, 48, 49, 50, 51, 52, 53, 54}; + +#else +#error "Board type has not been selected correctly" -#define DUMMY_DAT "qwertyuiopasdfghjklzxcvbnmmmmmm,./1234567890-=qwertyuiopasdfghjklzxcvbnm,./1234567890" +#endif -void print_help(void); -void do_noise(uint8 pin); -void do_everything(void); -void do_fast_gpio(void); +uint8 gpio_state[NR_GPIO_PINS]; + +const char* const dummy_dat = ("qwertyuiopasdfghjklzxcvbnmmmmmm,./1234567890-=" + "qwertyuiopasdfghjklzxcvbnm,./1234567890"); + +void cmd_print_help(void); +void cmd_adc_stats(void); +void cmd_stressful_adc_stats(void); +void cmd_everything(void); +void cmd_serial1_serial3(void); +void cmd_gpio_monitoring(void); +void cmd_sequential_adc_reads(void); +void cmd_gpio_qa(void); +void cmd_sequential_gpio_writes(void); +void cmd_gpio_toggling(void); +void cmd_sequential_pwm_test(void); +void cmd_pwm_sweep(void); +void cmd_servo_sweep(void); + +void measure_adc_noise(uint8 pin); +void fast_gpio(int pin); +void do_serials(HardwareSerial **serials, int n, unsigned baud); +void init_all_timers(uint16 prescale); void setup() { - /* Set up the LED to blink */ - pinMode(LED_PIN, OUTPUT); + // Set up the LED to blink + pinMode(BOARD_LED_PIN, OUTPUT); - /* Start up the serial ports */ + // Start up the serial ports Serial1.begin(9600); Serial2.begin(9600); Serial3.begin(9600); - /* Send a message out over COMM interface */ + // Send a message out over COMM interface COMM.println(" "); COMM.println(" __ __ _ _"); - COMM.println(" | \\/ | __ _ _ __ | | ___| |"); + COMM.println(" | \\/ | __ _ _ __ | | ___| |"); COMM.println(" | |\\/| |/ _` | '_ \\| |/ _ \\ |"); COMM.println(" | | | | (_| | |_) | | __/_|"); COMM.println(" |_| |_|\\__,_| .__/|_|\\___(_)"); @@ -55,409 +88,169 @@ void setup() { COMM.println(""); COMM.println(""); COMM.println("Maple interactive test program (type '?' for help)"); - COMM.println("------------------------------------------------------------"); + COMM.println("----------------------------------------------------------"); COMM.print("> "); } -void loop() { - toggle ^= 1; - digitalWrite(LED_PIN, toggle); +void loop () { + toggleLED(); delay(100); while(COMM.available()) { - input = COMM.read(); + uint8 input = COMM.read(); COMM.println(input); + switch(input) { - case 13: // Carriage Return - break; - case 32: // ' ' - COMM.println("spacebar, nice!"); - break; - case 63: // '?' - case 104: // 'h' - print_help(); - break; - case 117: // 'u' - SerialUSB.println("Hello World!"); - break; - case 119: // 'w' - Serial1.println("Hello World!"); - Serial2.println("Hello World!"); - Serial3.println("Hello World!"); - break; - case 109: // 'm' - COMM.println("Testing 57600 baud on USART1 and USART3. Press enter."); - Serial1.begin(57600); - Serial3.begin(57600); - while(!COMM.available()) { - Serial1.println(DUMMY_DAT); - Serial3.println(DUMMY_DAT); - if(Serial1.available()) { - Serial1.println(Serial1.read()); - delay(1000); - } - if(Serial3.available()) { - Serial3.println(Serial3.read()); - delay(1000); - } - } - COMM.read(); - COMM.println("Testing 115200 baud on USART1 and USART3. Press enter."); - Serial1.begin(115200); - Serial3.begin(115200); - while(!COMM.available()) { - Serial1.println(DUMMY_DAT); - Serial3.println(DUMMY_DAT); - if(Serial1.available()) { - Serial1.println(Serial1.read()); - delay(1000); - } - if(Serial3.available()) { - Serial3.println(Serial3.read()); - delay(1000); - } - } - COMM.read(); - COMM.println("Testing 9600 baud on USART1 and USART3. Press enter."); - Serial1.begin(9600); - Serial3.begin(9600); - while(!COMM.available()) { - Serial1.println(DUMMY_DAT); - Serial3.println(DUMMY_DAT); - if(Serial1.available()) { - Serial1.println(Serial1.read()); - delay(1000); - } - if(Serial3.available()) { - Serial3.println(Serial3.read()); - delay(1000); - } - } - COMM.read(); - COMM.println("Resetting USART1 and USART3..."); - Serial1.begin(9600); - Serial3.begin(9600); - break; - case 46: // '.' - while(!COMM.available()) { - Serial1.print("."); - Serial2.print("."); - Serial3.print("."); - SerialUSB.print("."); - } - break; - case 110: // 'n' - COMM.println("Taking ADC noise stats..."); - // turn off LED - digitalWrite(LED_PIN, 0); - // make sure to skip the TX/RX headers - for(uint32 i = 2; i<sizeof(adc_pins); i++) { - delay(5); - do_noise(adc_pins[i]); - } - break; - case 78: // 'N' - COMM.println("Taking ADC noise stats under duress..."); - // turn off LED - digitalWrite(LED_PIN, 0); - // make sure to skip the TX/RX headers - for(uint32 i = 2; i<sizeof(adc_pins); i++) { - // spool up PWM - for(uint32 j = 2; j<(uint32)sizeof(pwm_pins); j++) { - if(adc_pins[i] != pwm_pins[j]) { - pinMode(pwm_pins[j],PWM); - pwmWrite(pwm_pins[j], 1000 + i); - } - } - SerialUSB.print(DUMMY_DAT); - SerialUSB.print(DUMMY_DAT); - do_noise(adc_pins[i]); - for(uint32 j = 2; j<(uint32)sizeof(pwm_pins); j++) { - if(adc_pins[i] != pwm_pins[j]) { - pinMode(pwm_pins[j],OUTPUT); - digitalWrite(pwm_pins[j],0); - } - } - } - break; - case 101: // 'e' - do_everything(); - break; - case 87: // 'W' - while(!COMM.available()) { - Serial1.print(DUMMY_DAT); - Serial2.print(DUMMY_DAT); - Serial3.print(DUMMY_DAT); - } - break; - case 85: // 'U' - COMM.println("Dumping data to USB. Press enter."); - while(!COMM.available()) { - SerialUSB.print(DUMMY_DAT); - } - break; - case 103: // 'g' - COMM.print("Sequentially testing GPIO write on all possible headers except D0 and D1."); - COMM.println("Anything for next, ESC to stop."); - // turn off LED - digitalWrite(LED_PIN, 0); - // make sure to skip the TX/RX headers - for(uint32 i = 2; i<NUM_GPIO; i++) { - COMM.print("GPIO write out on header D"); - COMM.print(i, DEC); - COMM.println("..."); - pinMode(i, OUTPUT); - digitalWrite(i, tiddle); - while(!COMM.available()) { - tiddle ^= 1; - digitalWrite(i, tiddle); - } - digitalWrite(i, 0); - if((uint8)COMM.read() == (uint8)27) break; // ESC - } - break; - case 71: // 'G' - COMM.println("Flipping all GPIOs at the same time. Press enter."); - // turn off LED - digitalWrite(LED_PIN, 0); - // make sure to skip the TX/RX headers - for(uint32 i = 2; i<NUM_GPIO; i++) { - pinMode(i, OUTPUT); - } - while(!COMM.available()) { - tiddle ^= 1; - for(uint32 i = 2; i<NUM_GPIO; i++) { - digitalWrite(i, tiddle); - } - } - for(uint32 i = 2; i<NUM_GPIO; i++) { - digitalWrite(i, 0); - } - if((uint8)COMM.read() == (uint8)27) break; // ESC - break; - case 102: // 'f' - COMM.println("Wiggling GPIO header D4 as fast as possible in bursts. Press enter."); - pinMode(4,OUTPUT); - while(!COMM.available()) { - do_fast_gpio(); - delay(1); - } - break; - case 112: // 'p' - COMM.println("Sequentially testing PWM on all possible headers except D0 and D1. "); - COMM.println("Anything for next, ESC to stop."); - // turn off LED - digitalWrite(LED_PIN, 0); - // make sure to skip the TX/RX headers - for(uint32 i = 2; i<sizeof(pwm_pins); i++) { - COMM.print("PWM out on header D"); - COMM.print(pwm_pins[i], DEC); - COMM.println("..."); - pinMode(pwm_pins[i], PWM); - pwmWrite(pwm_pins[i], 16000); - while(!COMM.available()) { delay(10); } - pinMode(pwm_pins[i], OUTPUT); - digitalWrite(pwm_pins[i], 0); - if((uint8)COMM.read() == (uint8)27) break; // ESC - } - break; - case 80: // 'P' - COMM.println("Testing all PWM ports with a sweep. Press enter."); - // turn off LED - digitalWrite(LED_PIN, 0); - // make sure to skip the TX/RX pins - for(uint32 i = 2; i<sizeof(pwm_pins); i++) { - pinMode(pwm_pins[i], PWM); - pwmWrite(pwm_pins[i], 4000); - } - while(!COMM.available()) { - rate += 20; - if(rate > 65500) rate = 0; - for(uint32 i = 2; i<sizeof(pwm_pins); i++) { - pwmWrite(pwm_pins[i], rate); - } - delay(1); - } - for(uint32 i = 2; i<sizeof(pwm_pins); i++) { - pinMode(pwm_pins[i], OUTPUT); - } - break; - case 95: // '_' - COMM.println("Delaying for 5 seconds..."); - delay(5000); - break; - case 116: // 't' - break; - case 84: // 'T' - break; - case 115: // 's' - COMM.println("Testing all PWM headers with a servo sweep. Press enter."); - COMM.println(""); - // turn off LED - digitalWrite(LED_PIN, 0); - timer_init(1, 21); - timer_init(2, 21); - timer_init(3, 21); - timer_init(4, 21); - // make sure to skip the TX/RX headers - for(uint32 i = 2; i<sizeof(pwm_pins); i++) { - pinMode(pwm_pins[i], PWM); - pwmWrite(pwm_pins[i], 4000); - } - // 1.25ms = 4096counts = 0deg - // 1.50ms = 4915counts = 90deg - // 1.75ms = 5734counts = 180deg - rate = 4096; - while(!COMM.available()) { - rate += 20; - if(rate > 5734) rate = 4096; - for(uint32 i = 2; i<sizeof(pwm_pins); i++) { - pwmWrite(pwm_pins[i], rate); - } - delay(20); - } - for(uint32 i = 2; i<sizeof(pwm_pins); i++) { - pinMode(pwm_pins[i], OUTPUT); - } - timer_init(1, 1); - timer_init(2, 1); - timer_init(3, 1); - timer_init(4, 1); - Serial2.begin(9600); - COMM.println("(reset serial port)"); - break; - case 100: // 'd' - COMM.println("Pulling down D4, D22"); - pinMode(22,INPUT_PULLDOWN); - pinMode(4,INPUT_PULLDOWN); - while(!COMM.available()) { - delay(1); - } - COMM.read(); - COMM.println("Pulling up D4, D22"); - pinMode(22,INPUT_PULLUP); - pinMode(4,INPUT_PULLUP); - while(!COMM.available()) { - delay(1); - } - COMM.read(); - pinMode(4,OUTPUT); - break; - case 105: // 'i' - break; - case 73: // 'I' - break; - case 114: // 'r' - COMM.println("Monitoring GPIO read state changes. Press enter."); - // turn off LED - digitalWrite(LED_PIN, 0); - // make sure to skip the TX/RX headers - for(int i = 2; i<NUM_GPIO; i++) { - pinMode(i, INPUT_PULLDOWN); - gpio_state[i] = (uint8)digitalRead(i); - } - while(!COMM.available()) { - for(int i = 2; i<NUM_GPIO; i++) { - tiddle = (uint8)digitalRead(i); - if(tiddle != gpio_state[i]) { - COMM.print("State change on header D"); - COMM.print(i,DEC); - if(tiddle) COMM.println(":\tHIGH"); - else COMM.println(":\tLOW"); - gpio_state[i] = tiddle; - } - } - } - for(int i = 2; i<NUM_GPIO; i++) { - pinMode(i, OUTPUT); - } - break; - case 97: // 'a' - COMM.print("Sequentially reading each ADC port."); - COMM.println("Anything for next, ESC to stop."); - // turn off LED - digitalWrite(LED_PIN, 0); - // make sure to skip the TX/RX headers - for(uint32 i = 2; i<sizeof(adc_pins); i++) { - COMM.print("Reading on header D"); - COMM.print(adc_pins[i], DEC); - COMM.println("..."); - pinMode(adc_pins[i], INPUT_ANALOG); - while(!COMM.available()) { - sample = analogRead(adc_pins[i]); - COMM.print(adc_pins[i],DEC); - COMM.print("\t"); - COMM.print(sample,DEC); - COMM.print("\t"); - COMM.print("|"); - for(int j = 0; j<4096; j+= 100) { - if(sample >= j) COMM.print("#"); - else COMM.print(" "); - } - COMM.print("| "); - for(int j = 0; j<12; j++) { - if(sample & (1 << (11-j))) COMM.print("1"); - else COMM.print("0"); - } - COMM.println(""); - } - pinMode(adc_pins[i], OUTPUT); - digitalWrite(adc_pins[i], 0); - if((uint8)COMM.read() == (uint8)27) break; // ESC - } - break; - case 43: // '+' - COMM.println("Doing QA testing for 37 GPIO pins..."); - // turn off LED - digitalWrite(LED_PIN, 0); - for(int i = 0; i<NUM_GPIO; i++) { - pinMode(i, INPUT); - gpio_state[i] = 0; //(uint8)digitalRead(i); - } - COMM.println("Waiting to start..."); - while(digitalRead(0) != 1 && !COMM.available()) { - continue; - } - for(int i=0; i<38; i++) { - if(i==13) { - COMM.println("Not Checking D13 (LED)"); - continue; - } - COMM.print("Checking D"); - COMM.print(i,DEC); - while(digitalRead(i) == 0) continue; - for(int j=0; j<NUM_GPIO; j++) { - if(digitalRead(j) && j!=i) { - COMM.print(": FAIL ########################### D"); - COMM.println(j, DEC); - break; - } - } - while(digitalRead(i) == 1) continue; - for(int j=0; j<NUM_GPIO; j++) { - if(digitalRead(j) && j!=i) { - COMM.print(": FAIL ########################### D"); - COMM.println(j, DEC); - break; - } - } - COMM.println(": Ok!"); - } - for(int i = 0; i<NUM_GPIO; i++) { - pinMode(i, OUTPUT); - digitalWrite(i, 0); - } - break; - default: - COMM.print("Unexpected: "); - COMM.println(input); + case '\r': + break; + + case ' ': + COMM.println("spacebar, nice!"); + break; + + case '?': + case 'h': + cmd_print_help(); + break; + + case 'u': + SerialUSB.println("Hello World!"); + break; + + case 'w': + Serial1.println("Hello World!"); + Serial2.println("Hello World!"); + Serial3.println("Hello World!"); + break; + + case 'm': + cmd_serial1_serial3(); + break; + + case '.': + while(!COMM.available()) { + Serial1.print("."); + Serial2.print("."); + Serial3.print("."); + SerialUSB.print("."); + } + break; + + case 'n': + cmd_adc_stats(); + break; + + case 'N': + cmd_stressful_adc_stats(); + break; + + case 'e': + cmd_everything(); + break; + + case 'W': + while(!COMM.available()) { + Serial1.print(dummy_dat); + Serial2.print(dummy_dat); + Serial3.print(dummy_dat); + } + break; + + case 'U': + COMM.println("Dumping data to USB. Press any key."); + while(!COMM.available()) { + SerialUSB.print(dummy_dat); + } + break; + + case 'g': + cmd_sequential_gpio_writes(); + break; + + case 'G': + cmd_gpio_toggling(); + break; + + case 'f': + COMM.println("Wiggling D4 as fast as possible in bursts. " + "Press any key."); + pinMode(4,OUTPUT); + while(!COMM.available()) { + fast_gpio(4); + delay(1); + } + break; + + case 'p': + cmd_sequential_pwm_test(); + break; + + case 'P': + cmd_pwm_sweep(); + break; + + case '_': + COMM.println("Delaying for 5 seconds..."); + delay(5000); + break; + + case 't': // TODO + break; + + case 'T': // TODO + break; + + case 's': + cmd_servo_sweep(); + break; + + case 'd': + COMM.println("Pulling down D4, D22. Press any key."); + pinMode(22,INPUT_PULLDOWN); + pinMode(4,INPUT_PULLDOWN); + while(!COMM.available()) { + continue; + } + COMM.println("Pulling up D4, D22. Press any key."); + pinMode(22,INPUT_PULLUP); + pinMode(4,INPUT_PULLUP); + while(!COMM.available()) { + continue; + } + COMM.read(); + pinMode(4,OUTPUT); + break; + + case 'i': // TODO + break; + + case 'I': // TODO + break; + + case 'r': + cmd_gpio_monitoring(); + break; + + case 'a': + cmd_sequential_adc_reads(); + break; + + case '+': + cmd_gpio_qa(); + break; + + default: // ------------------------------- + COMM.print("Unexpected: "); + COMM.print(input); + COMM.println(", press h for help."); } + COMM.print("> "); } } -void print_help(void) { +void cmd_print_help(void) { COMM.println(""); //COMM.println("Command Listing\t(# means any digit)"); COMM.println("Command Listing"); @@ -469,28 +262,29 @@ void print_help(void) { COMM.println("\ta: show realtime ADC info"); COMM.println("\t.: echo '.' until new input"); COMM.println("\tu: print Hello World on USB"); - COMM.println("\t_: try to do as little as possible for a couple seconds (delay)"); + COMM.println("\t_: do as little as possible for a couple seconds (delay)"); COMM.println("\tp: test all PWM channels sequentially"); COMM.println("\tW: dump data as fast as possible on all 3 USARTS"); COMM.println("\tU: dump data as fast as possible on USB"); COMM.println("\tg: toggle all GPIOs sequentialy"); COMM.println("\tG: toggle all GPIOs at the same time"); COMM.println("\tf: toggle GPIO D4 as fast as possible in bursts"); - COMM.println("\tP: test all PWM channels at the same time with different speeds/sweeps"); - COMM.println("\tr: read in GPIO status changes and print them in realtime"); - COMM.println("\ts: output a sweeping SERVO PWM on all PWM channels"); - COMM.println("\tm: output serial data dumps on USART1 and USART3 with various rates"); + COMM.println("\tP: simultaneously test all PWM channels with different " + "speeds/sweeps"); + COMM.println("\tr: Monitor and print GPIO status changes"); + COMM.println("\ts: output a sweeping servo PWM on all PWM channels"); + COMM.println("\tm: output data on USART1 and USART3 with various rates"); COMM.println("\t+: test shield mode (for QA, will disrupt Serial2!)"); COMM.println("Unimplemented:"); COMM.println("\te: do everything all at once until new input"); - COMM.println("\tt: output a 1khz squarewave on all GPIOs as well as possible"); - COMM.println("\tT: output a 1hz squarewave on all GPIOs as well as possible"); + COMM.println("\tt: output a 1khz squarewave on all GPIOs"); + COMM.println("\tT: output a 1hz squarewave on all GPIOs"); COMM.println("\ti: print out a bunch of info about system state"); COMM.println("\tI: print out status of all headers"); } -void do_noise(uint8 pin) { // TODO +void measure_adc_noise(uint8 pin) { // TODO uint16 data[100]; float mean = 0; //float stddev = 0; @@ -512,12 +306,43 @@ void do_noise(uint8 pin) { // TODO COMM.print("header: D"); COMM.print(pin,DEC); COMM.print("\tn: "); COMM.print(100,DEC); COMM.print("\tmean: "); COMM.print(mean); - COMM.print("\tvar: "); COMM.println(M2/99.0); + COMM.print("\tvariance: "); COMM.println(M2/99.0); pinMode(pin, OUTPUT); } -void do_everything(void) { // TODO - // TODO +void cmd_adc_stats(void) { + COMM.println("Taking ADC noise stats..."); + digitalWrite(BOARD_LED_PIN, 0); + for(uint32 i = 0; i<sizeof(adc_pins); i++) { + delay(5); + measure_adc_noise(adc_pins[i]); + } +} + +void cmd_stressful_adc_stats(void) { + COMM.println("Taking ADC noise stats under duress..."); + digitalWrite(BOARD_LED_PIN, 0); + for(uint32 i = 0; i<sizeof(adc_pins); i++) { + // spool up PWM + for(uint32 j = 2; j<(uint32)sizeof(pwm_pins); j++) { + if(adc_pins[i] != pwm_pins[j]) { + pinMode(pwm_pins[j],PWM); + pwmWrite(pwm_pins[j], 1000 + i); + } + } + SerialUSB.print(dummy_dat); + SerialUSB.print(dummy_dat); + measure_adc_noise(adc_pins[i]); + for(uint32 j = 2; j<(uint32)sizeof(pwm_pins); j++) { + if(adc_pins[i] != pwm_pins[j]) { + pinMode(pwm_pins[j],OUTPUT); + digitalWrite(pwm_pins[j],0); + } + } + } +} + +void cmd_everything(void) { // TODO // print to usart // print to usb // toggle gpios @@ -525,26 +350,284 @@ void do_everything(void) { // TODO COMM.println("(unimplemented)"); } -void do_fast_gpio(void) { - // header D4 is on port B and is pin 5 on the uC - gpio_write_bit(GPIOB_BASE, 5, 1); gpio_write_bit(GPIOB_BASE, 5, 0); - gpio_write_bit(GPIOB_BASE, 5, 1); gpio_write_bit(GPIOB_BASE, 5, 0); - gpio_write_bit(GPIOB_BASE, 5, 1); gpio_write_bit(GPIOB_BASE, 5, 0); - gpio_write_bit(GPIOB_BASE, 5, 1); gpio_write_bit(GPIOB_BASE, 5, 0); - gpio_write_bit(GPIOB_BASE, 5, 1); gpio_write_bit(GPIOB_BASE, 5, 0); - gpio_write_bit(GPIOB_BASE, 5, 1); gpio_write_bit(GPIOB_BASE, 5, 0); - gpio_write_bit(GPIOB_BASE, 5, 1); gpio_write_bit(GPIOB_BASE, 5, 0); - gpio_write_bit(GPIOB_BASE, 5, 1); gpio_write_bit(GPIOB_BASE, 5, 0); - gpio_write_bit(GPIOB_BASE, 5, 1); gpio_write_bit(GPIOB_BASE, 5, 0); - gpio_write_bit(GPIOB_BASE, 5, 1); gpio_write_bit(GPIOB_BASE, 5, 0); - gpio_write_bit(GPIOB_BASE, 5, 1); gpio_write_bit(GPIOB_BASE, 5, 0); - gpio_write_bit(GPIOB_BASE, 5, 1); gpio_write_bit(GPIOB_BASE, 5, 0); - gpio_write_bit(GPIOB_BASE, 5, 1); gpio_write_bit(GPIOB_BASE, 5, 0); +void fast_gpio(int maple_pin) { + GPIO_Port *port = PIN_MAP[maple_pin].port; + uint32 pin = PIN_MAP[maple_pin].pin; + + gpio_write_bit(port, pin, 1); gpio_write_bit(port, pin, 0); + gpio_write_bit(port, pin, 1); gpio_write_bit(port, pin, 0); + gpio_write_bit(port, pin, 1); gpio_write_bit(port, pin, 0); + gpio_write_bit(port, pin, 1); gpio_write_bit(port, pin, 0); + gpio_write_bit(port, pin, 1); gpio_write_bit(port, pin, 0); + gpio_write_bit(port, pin, 1); gpio_write_bit(port, pin, 0); + gpio_write_bit(port, pin, 1); gpio_write_bit(port, pin, 0); + gpio_write_bit(port, pin, 1); gpio_write_bit(port, pin, 0); + gpio_write_bit(port, pin, 1); gpio_write_bit(port, pin, 0); + gpio_write_bit(port, pin, 1); gpio_write_bit(port, pin, 0); + gpio_write_bit(port, pin, 1); gpio_write_bit(port, pin, 0); + gpio_write_bit(port, pin, 1); gpio_write_bit(port, pin, 0); + gpio_write_bit(port, pin, 1); gpio_write_bit(port, pin, 0); +} + +void cmd_serial1_serial3(void) { + HardwareSerial *serial_1_and_3[] = {&Serial1, &Serial3}; + + COMM.println("Testing 57600 baud on USART1 and USART3. Press any key."); + do_serials(serial_1_and_3, 2, 57600); + COMM.read(); + + COMM.println("Testing 115200 baud on USART1 and USART3. Press any key."); + do_serials(serial_1_and_3, 2, 115200); + COMM.read(); + + COMM.println("Testing 9600 baud on USART1 and USART3. Press any key."); + do_serials(serial_1_and_3, 2, 9600); + COMM.read(); + + COMM.println("Resetting USART1 and USART3..."); + Serial1.begin(9600); + Serial3.begin(9600); +} + +void do_serials(HardwareSerial **serials, int n, unsigned baud) { + for (int i = 0; i < n; i++) { + serials[i]->begin(9600); + } + while (!COMM.available()) { + for (int i = 0; i < n; i++) { + serials[i]->println(dummy_dat); + if (serials[i]->available()) { + serials[i]->println(serials[i]->read()); + delay(1000); + } + } + } +} + +void cmd_gpio_monitoring(void) { + COMM.println("Monitoring GPIO read state changes. Press any key."); + digitalWrite(BOARD_LED_PIN, 0); + // make sure to skip the TX/RX headers + for(int i = 2; i<NR_GPIO_PINS; i++) { + pinMode(i, INPUT_PULLDOWN); + gpio_state[i] = (uint8)digitalRead(i); + } + while(!COMM.available()) { + for(int i = 2; i<NR_GPIO_PINS; i++) { + uint8 current_state = (uint8)digitalRead(i); + if(current_state != gpio_state[i]) { + COMM.print("State change on header D"); + COMM.print(i,DEC); + if(current_state) COMM.println(":\tHIGH"); + else COMM.println(":\tLOW"); + gpio_state[i] = current_state; + } + } + } + for(int i = 2; i<NR_GPIO_PINS; i++) { + pinMode(i, OUTPUT); + } } +void cmd_sequential_adc_reads(void) { + COMM.print("Sequentially reading each ADC port."); + COMM.println("Press any key for next port, or ESC to stop."); + digitalWrite(LED_PIN, 0); + // make sure to skip the TX/RX headers + for(uint32 i = 2; i<sizeof(adc_pins); i++) { + COMM.print("Reading on header D"); + COMM.print(adc_pins[i], DEC); + COMM.println("..."); + pinMode(adc_pins[i], INPUT_ANALOG); + while(!COMM.available()) { + int sample = analogRead(adc_pins[i]); + COMM.print(adc_pins[i],DEC); + COMM.print("\t"); + COMM.print(sample,DEC); + COMM.print("\t"); + COMM.print("|"); + for(int j = 0; j<4096; j+= 100) { + if(sample >= j) COMM.print("#"); + else COMM.print(" "); + } + COMM.print("| "); + for(int j = 0; j<12; j++) { + if(sample & (1 << (11-j))) COMM.print("1"); + else COMM.print("0"); + } + COMM.println(""); + } + pinMode(adc_pins[i], OUTPUT); + digitalWrite(adc_pins[i], 0); + if((uint8)COMM.read() == ESC) break; + } +} + +void cmd_gpio_qa(void) { + COMM.println("Doing QA testing for most GPIO pins..."); + digitalWrite(BOARD_LED_PIN, 0); + for(int i = 0; i<NR_GPIO_PINS; i++) { + pinMode(i, INPUT); + gpio_state[i] = 0; + } + COMM.println("Waiting to start..."); + while(digitalRead(0) != 1 && !COMM.available()) { + continue; + } + for(int i=0; i<38; i++) { + if(i == BOARD_LED_PIN) { + COMM.println("Not checking LED"); + continue; + } + COMM.print("Checking D"); + COMM.print(i,DEC); + while(digitalRead(i) == 0) continue; + for(int j=0; j<NR_GPIO_PINS; j++) { + if(digitalRead(j) && j!=i) { + COMM.print(": FAIL ########################### D"); + COMM.println(j, DEC); + break; + } + } + while(digitalRead(i) == 1) continue; + for(int j=0; j<NR_GPIO_PINS; j++) { + if(digitalRead(j) && j!=i) { + COMM.print(": FAIL ########################### D"); + COMM.println(j, DEC); + break; + } + } + COMM.println(": Ok!"); + } + for(int i = 0; i<NR_GPIO_PINS; i++) { + pinMode(i, OUTPUT); + digitalWrite(i, 0); + } +} + +void cmd_sequential_gpio_writes(void) { + COMM.print("Sequentially toggling all pins except D0, D1. "); + COMM.println("Anything for next, ESC to stop."); + digitalWrite(BOARD_LED_PIN, 0); + // make sure to skip the TX/RX headers + for(uint32 i = 2; i<NR_GPIO_PINS; i++) { + COMM.print("GPIO write out on header D"); + COMM.print(i, DEC); + COMM.println("..."); + pinMode(i, OUTPUT); + do { + togglePin(i); + } while(!COMM.available()); + digitalWrite(i, 0); + if((uint8)COMM.read() == ESC) break; + } +} + +void cmd_gpio_toggling(void) { + COMM.println("Toggling all GPIOs simultaneously. Press any key."); + digitalWrite(BOARD_LED_PIN, 0); + // make sure to skip the TX/RX headers + for(uint32 i = 2; i<NR_GPIO_PINS; i++) { + pinMode(i, OUTPUT); + } + while(!COMM.available()) { + for(uint32 i = 2; i<NR_GPIO_PINS; i++) { + togglePin(i); + } + } + for(uint32 i = 2; i<NR_GPIO_PINS; i++) { + digitalWrite(i, 0); + } +} + +void cmd_sequential_pwm_test(void) { + COMM.println("Sequentially testing PWM on all possible headers " + "except D0 and D1."); + COMM.println("Press any key for next, ESC to stop."); + digitalWrite(BOARD_LED_PIN, 0); + // make sure to skip the TX/RX headers + for(uint32 i = 2; i<sizeof(pwm_pins); i++) { + COMM.print("PWM out on header D"); + COMM.print(pwm_pins[i], DEC); + COMM.println("..."); + pinMode(pwm_pins[i], PWM); + pwmWrite(pwm_pins[i], 16000); + while(!COMM.available()) { delay(10); } + pinMode(pwm_pins[i], OUTPUT); + digitalWrite(pwm_pins[i], 0); + if((uint8)COMM.read() == ESC) break; + } +} + +void cmd_pwm_sweep(void) { + COMM.println("Testing all PWM ports with a sweep. Press any key."); + digitalWrite(BOARD_LED_PIN, 0); + // make sure to skip the TX/RX pins + for(uint32 i = 2; i<sizeof(pwm_pins); i++) { + pinMode(pwm_pins[i], PWM); + pwmWrite(pwm_pins[i], 4000); + } + while(!COMM.available()) { + rate += 20; + if(rate > 65500) rate = 0; + for(uint32 i = 2; i<sizeof(pwm_pins); i++) { + pwmWrite(pwm_pins[i], rate); + } + delay(1); + } + for(uint32 i = 2; i<sizeof(pwm_pins); i++) { + pinMode(pwm_pins[i], OUTPUT); + } +} + +void cmd_servo_sweep(void) { + COMM.println("Testing all PWM headers with a servo sweep. Press any key."); + COMM.println(); + digitalWrite(BOARD_LED_PIN, 0); + init_all_timers(21); + // make sure to skip the TX/RX headers + for(uint32 i = 2; i<sizeof(pwm_pins); i++) { + pinMode(pwm_pins[i], PWM); + pwmWrite(pwm_pins[i], 4000); + } + // 1.25ms = 4096counts = 0deg + // 1.50ms = 4915counts = 90deg + // 1.75ms = 5734counts = 180deg + rate = 4096; + while(!COMM.available()) { + rate += 20; + if(rate > 5734) rate = 4096; + for(uint32 i = 2; i<sizeof(pwm_pins); i++) { + pwmWrite(pwm_pins[i], rate); + } + delay(20); + } + for(uint32 i = 2; i<sizeof(pwm_pins); i++) { + pinMode(pwm_pins[i], OUTPUT); + } + init_all_timers(1); + Serial2.begin(9600); + COMM.println("(reset serial port)"); +} + +void init_all_timers(uint16 prescale) { + timer_init(TIMER1, prescale); + timer_init(TIMER2, prescale); + timer_init(TIMER3, prescale); +#if NR_TIMERS >= 4 + timer_init(TIMER4, prescale); +#elif NR_TIMERS >= 8 // TODO test this on maple native + timer_init(TIMER5, prescale); + timer_init(TIMER6, prescale); + timer_init(TIMER7, prescale); + timer_init(TIMER8, prescale); +#endif +} + + // Force init to be called *first*, i.e. before static object allocation. // Otherwise, statically allocated object that need libmaple may fail. - __attribute__(( constructor )) void premain() { +__attribute__(( constructor )) void premain() { init(); } diff --git a/libmaple/gpio.c b/libmaple/gpio.c index 3940837..71e5230 100644 --- a/libmaple/gpio.c +++ b/libmaple/gpio.c @@ -34,8 +34,9 @@ void gpio_init(void) { rcc_clk_enable(RCC_GPIOA); rcc_clk_enable(RCC_GPIOB); rcc_clk_enable(RCC_GPIOC); +#if NR_GPIO_PORTS >= 4 /* Maple, but not Maple Mini */ rcc_clk_enable(RCC_GPIOD); -#if NR_GPIO_PORTS >= 7 +#elif NR_GPIO_PORTS >= 7 /* Maple Native (high density only) */ rcc_clk_enable(RCC_GPIOE); rcc_clk_enable(RCC_GPIOF); rcc_clk_enable(RCC_GPIOG); diff --git a/libmaple/libmaple.h b/libmaple/libmaple.h index 74488ab..225d7c4 100644 --- a/libmaple/libmaple.h +++ b/libmaple/libmaple.h @@ -43,7 +43,7 @@ #endif /* MCU-specific configuration */ -#ifdef MCU_STM32F103RB +#if defined(MCU_STM32F103RB) /* e.g., LeafLabs Maple */ /* Number of GPIO ports (GPIOA, GPIOB, etc.) */ @@ -80,8 +80,8 @@ #define STACK_TOP 0x20000800 /* Debug port settings (from ASSERT) */ - #define ERROR_LED_PORT GPIOA_BASE - #define ERROR_LED_PIN 5 + #define ERROR_LED_PORT GPIOB_BASE + #define ERROR_LED_PIN 12 #define ERROR_USART_NUM USART2 #define ERROR_USART_BAUD 9600 #define ERROR_TX_PORT GPIOA_BASE @@ -97,15 +97,14 @@ #define BITBAND_SRAM_BASE 0x22000000 #define BITBAND_PERI_REF 0x40000000 #define BITBAND_PERI_BASE 0x42000000 -#endif -#ifdef MCU_STM32F103ZE +#elif defined(MCU_STM32F103ZE) /* e.g., LeafLabs Maple Native */ #define NR_GPIO_PORTS 7 - #define NR_GPIO_PINS 63 + #define NR_GPIO_PINS 100 #define NR_TIMERS 8 - #define NR_USART 3 + #define NR_USART 5 /* NB: 4 and 5 are UART only */ #define NR_FSMC 1 #define NR_DAC_PINS 2 @@ -135,9 +134,8 @@ #define BITBAND_SRAM_BASE 0x22000000 #define BITBAND_PERI_REF 0x40000000 #define BITBAND_PERI_BASE 0x42000000 -#endif -#ifdef MCU_STM32F103CB +#elif defined(MCU_STM32F103CB) /* e.g., LeafLabs Maple Mini */ #define NR_GPIO_PORTS 3 @@ -151,7 +149,7 @@ #define VCOM_ID_PRODUCT 0x0005 #define USB_DISC_BANK GPIOB_BASE #define USB_DISC_PIN 9 - #define USB_CONFIG_MAX_POWER (100 >> 1) /* WTF does this mean */ + #define USB_CONFIG_MAX_POWER (100 >> 1) #define RESET_DELAY 100 #define USER_ADDR_ROM 0x08005000 @@ -174,12 +172,12 @@ #define BITBAND_SRAM_BASE 0x22000000 #define BITBAND_PERI_REF 0x40000000 #define BITBAND_PERI_BASE 0x42000000 -#endif -/* Make sure MCU-specific settings were defined */ -#ifndef NR_GPIO_PORTS -#error "No MCU type specified. Add something like -DMCU_STM32F103RB " \ +#else + +#error "No MCU type specified. Add something like -DMCU_STM32F103RB " \ "to your compiler arguments (probably in a Makefile)." + #endif /* Requires board configuration info */ diff --git a/libmaple/timers.h b/libmaple/timers.h index 8d28f60..99bcab6 100644 --- a/libmaple/timers.h +++ b/libmaple/timers.h @@ -208,6 +208,8 @@ typedef enum { TIMER4, /*< General purpose timer TIM4 */ #if NR_TIMERS >= 8 TIMER5, /*< General purpose timer TIM5; high density only */ + /* FIXME maple native: put timers 6 and 7 back in and make the + corresponding changes to timers.c */ /* TIMER6, /\*< Basic timer TIM6; high density only *\/ */ /* TIMER7, /\*< Basic timer TIM7; high density only *\/ */ TIMER8, /*< Advanced control timer TIM8; high density only */ diff --git a/libmaple/usb/usb.c b/libmaple/usb/usb.c index 4e86ed0..d875785 100644 --- a/libmaple/usb/usb.c +++ b/libmaple/usb/usb.c @@ -332,9 +332,9 @@ void usbWaitReset(void) { * This function will quickly copy up to 64 bytes of data (out of an * arbitrarily large buffer) into the USB peripheral TX buffer and return the * number placed in that buffer. It is up to usercode to divide larger packets - * into 64-byte chunks to guarantee delivery. + * into 64-byte chunks to guarantee delivery. + * * - * */ void usbBlockingSendByte(char ch) { while (countTx); @@ -345,7 +345,8 @@ void usbBlockingSendByte(char ch) { while (countTx); } uint32 usbSendBytes(uint8* sendBuf, uint32 len) { - /* any checks on connection (via dtr/rts) done upstream in wirish or by user */ + /* any checks on connection (via dtr/rts) done upstream in wirish or + by user */ /* last xmit hasnt finished, abort */ if (countTx) { @@ -361,8 +362,8 @@ uint32 usbSendBytes(uint8* sendBuf, uint32 len) { if (len) { UserToPMABufferCopy(sendBuf,VCOM_TX_ADDR, len); _SetEPTxCount(VCOM_TX_ENDP, len); - _SetEPTxValid(VCOM_TX_ENDP); countTx += len; + _SetEPTxValid(VCOM_TX_ENDP); } return len; diff --git a/libraries/LiquidCrystal/LiquidCrystal.cpp b/libraries/LiquidCrystal/LiquidCrystal.cpp new file mode 100644 index 0000000..52f0308 --- /dev/null +++ b/libraries/LiquidCrystal/LiquidCrystal.cpp @@ -0,0 +1,324 @@ +#include "LiquidCrystal.h" + +#include <stdio.h> +#include <string.h> +#include "WProgram.h" + +// When the display powers up, it is configured as follows: +// +// 1. Display clear +// 2. Function set: +// DL = 1; 8-bit interface data +// N = 0; 1-line display +// F = 0; 5x8 dot character font +// 3. Display on/off control: +// D = 0; Display off +// C = 0; Cursor off +// B = 0; Blinking off +// 4. Entry mode set: +// I/D = 1; Increment by 1 +// S = 0; No shift +// +// Note, however, that resetting the Arduino doesn't reset the LCD, so we +// can't assume that its in that state when a sketch starts (and the +// LiquidCrystal constructor is called). + +// This library has been modified to be compatible with the LeafLabs Maple; +// very conservative timing is used due to problems with delayMicroseconds() +// that should be fixed in the 0.0.7 release of the libmaple. [bnewbold] + +LiquidCrystal::LiquidCrystal(uint8 rs, uint8 rw, uint8 enable, + uint8 d0, uint8 d1, uint8 d2, uint8 d3, + uint8 d4, uint8 d5, uint8 d6, uint8 d7) +{ + init(0, rs, rw, enable, d0, d1, d2, d3, d4, d5, d6, d7); +} + +LiquidCrystal::LiquidCrystal(uint8 rs, uint8 enable, + uint8 d0, uint8 d1, uint8 d2, uint8 d3, + uint8 d4, uint8 d5, uint8 d6, uint8 d7) +{ + init(0, rs, 255, enable, d0, d1, d2, d3, d4, d5, d6, d7); +} + +LiquidCrystal::LiquidCrystal(uint8 rs, uint8 rw, uint8 enable, + uint8 d0, uint8 d1, uint8 d2, uint8 d3) +{ + init(1, rs, rw, enable, d0, d1, d2, d3, 0, 0, 0, 0); +} + +LiquidCrystal::LiquidCrystal(uint8 rs, uint8 enable, + uint8 d0, uint8 d1, uint8 d2, uint8 d3) +{ + init(1, rs, 255, enable, d0, d1, d2, d3, 0, 0, 0, 0); +} + +void LiquidCrystal::init(uint8 fourbitmode, uint8 rs, uint8 rw, uint8 enable, + uint8 d0, uint8 d1, uint8 d2, uint8 d3, + uint8 d4, uint8 d5, uint8 d6, uint8 d7) +{ + _rs_pin = rs; + _rw_pin = rw; + _enable_pin = enable; + + _data_pins[0] = d0; + _data_pins[1] = d1; + _data_pins[2] = d2; + _data_pins[3] = d3; + _data_pins[4] = d4; + _data_pins[5] = d5; + _data_pins[6] = d6; + _data_pins[7] = d7; + + pinMode(_rs_pin, OUTPUT); + // we can save 1 pin by not using RW. Indicate by passing 255 instead of pin# + if (_rw_pin != 255) { + pinMode(_rw_pin, OUTPUT); + } + pinMode(_enable_pin, OUTPUT); + + if (fourbitmode) + _displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS; + else + _displayfunction = LCD_8BITMODE | LCD_1LINE | LCD_5x8DOTS; + + // TODO: bnewbold, re-enable this? + begin(16, 1); +} + +void LiquidCrystal::begin(uint8 cols, uint8 lines, uint8 dotsize) { + if (lines > 1) { + _displayfunction |= LCD_2LINE; + } + _numlines = lines; + _currline = 0; + + // for some 1 line displays you can select a 10 pixel high font + if ((dotsize != 0) && (lines == 1)) { + _displayfunction |= LCD_5x10DOTS; + } + + // SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION! + // according to datasheet, we need at least 40ms after power rises above 2.7V + // before sending commands. Arduino can turn on way befer 4.5V so we'll wait 50 + delay(50); // Maple mod + //delayMicroseconds(50000); + // Now we pull both RS and R/W low to begin commands + digitalWrite(_rs_pin, LOW); + digitalWrite(_enable_pin, LOW); + if (_rw_pin != 255) { + digitalWrite(_rw_pin, LOW); + } + + //put the LCD into 4 bit or 8 bit mode + if (! (_displayfunction & LCD_8BITMODE)) { + // this is according to the hitachi HD44780 datasheet + // figure 24, pg 46 + + // we start in 8bit mode, try to set 4 bit mode + write4bits(0x03); + delay(5); // Maple mod + //delayMicroseconds(4500); // wait min 4.1ms + + // second try + write4bits(0x03); + delay(5); // Maple mod + //delayMicroseconds(4500); // wait min 4.1ms + + // third go! + write4bits(0x03); + delay(1); // Maple mod + //delayMicroseconds(150); + + // finally, set to 8-bit interface + write4bits(0x02); + } else { + // this is according to the hitachi HD44780 datasheet + // page 45 figure 23 + + // Send function set command sequence + command(LCD_FUNCTIONSET | _displayfunction); + delay(5); // Maple mod + //delayMicroseconds(4500); // wait more than 4.1ms + + // second try + command(LCD_FUNCTIONSET | _displayfunction); + delay(1); // Maple mod + //delayMicroseconds(150); + + // third go + command(LCD_FUNCTIONSET | _displayfunction); + } + + // finally, set # lines, font size, etc. + command(LCD_FUNCTIONSET | _displayfunction); + + // turn the display on with no cursor or blinking default + _displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF; + display(); + + // clear it off + clear(); + + // Initialize to default text direction (for romance languages) + _displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT; + // set the entry mode + command(LCD_ENTRYMODESET | _displaymode); + +} + +/********** high level commands, for the user! */ +void LiquidCrystal::clear() +{ + command(LCD_CLEARDISPLAY); // clear display, set cursor position to zero + delay(2); // Maple mod + //delayMicroseconds(2000); // this command takes a long time! +} + +void LiquidCrystal::home() +{ + command(LCD_RETURNHOME); // set cursor position to zero + delay(2); // Maple mod + //delayMicroseconds(2000); // this command takes a long time! +} + +void LiquidCrystal::setCursor(uint8 col, uint8 row) +{ + int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 }; + if ( row > _numlines ) { + row = _numlines-1; // we count rows starting w/0 + } + + command(LCD_SETDDRAMADDR | (col + row_offsets[row])); +} + +// Turn the display on/off (quickly) +void LiquidCrystal::noDisplay() { + _displaycontrol &= ~LCD_DISPLAYON; + command(LCD_DISPLAYCONTROL | _displaycontrol); +} +void LiquidCrystal::display() { + _displaycontrol |= LCD_DISPLAYON; + command(LCD_DISPLAYCONTROL | _displaycontrol); +} + +// Turns the underline cursor on/off +void LiquidCrystal::noCursor() { + _displaycontrol &= ~LCD_CURSORON; + command(LCD_DISPLAYCONTROL | _displaycontrol); +} +void LiquidCrystal::cursor() { + _displaycontrol |= LCD_CURSORON; + command(LCD_DISPLAYCONTROL | _displaycontrol); +} + +// Turn on and off the blinking cursor +void LiquidCrystal::noBlink() { + _displaycontrol &= ~LCD_BLINKON; + command(LCD_DISPLAYCONTROL | _displaycontrol); +} +void LiquidCrystal::blink() { + _displaycontrol |= LCD_BLINKON; + command(LCD_DISPLAYCONTROL | _displaycontrol); +} + +// These commands scroll the display without changing the RAM +void LiquidCrystal::scrollDisplayLeft(void) { + command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT); +} +void LiquidCrystal::scrollDisplayRight(void) { + command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT); +} + +// This is for text that flows Left to Right +void LiquidCrystal::leftToRight(void) { + _displaymode |= LCD_ENTRYLEFT; + command(LCD_ENTRYMODESET | _displaymode); +} + +// This is for text that flows Right to Left +void LiquidCrystal::rightToLeft(void) { + _displaymode &= ~LCD_ENTRYLEFT; + command(LCD_ENTRYMODESET | _displaymode); +} + +// This will 'right justify' text from the cursor +void LiquidCrystal::autoscroll(void) { + _displaymode |= LCD_ENTRYSHIFTINCREMENT; + command(LCD_ENTRYMODESET | _displaymode); +} + +// This will 'left justify' text from the cursor +void LiquidCrystal::noAutoscroll(void) { + _displaymode &= ~LCD_ENTRYSHIFTINCREMENT; + command(LCD_ENTRYMODESET | _displaymode); +} + +// Allows us to fill the first 8 CGRAM locations +// with custom characters +void LiquidCrystal::createChar(uint8 location, uint8 charmap[]) { + location &= 0x7; // we only have 8 locations 0-7 + command(LCD_SETCGRAMADDR | (location << 3)); + for (int i=0; i<8; i++) { + write(charmap[i]); + } +} + +/*********** mid level commands, for sending data/cmds */ + +inline void LiquidCrystal::command(uint8 value) { + send(value, LOW); +} + +inline void LiquidCrystal::write(uint8 value) { + send(value, HIGH); +} + +/************ low level data pushing commands **********/ + +// write either command or data, with automatic 4/8-bit selection +void LiquidCrystal::send(uint8 value, uint8 mode) { + digitalWrite(_rs_pin, mode); + + // if there is a RW pin indicated, set it low to Write + if (_rw_pin != 255) { + digitalWrite(_rw_pin, LOW); + } + + if (_displayfunction & LCD_8BITMODE) { + write8bits(value); + } else { + write4bits(value>>4); + write4bits(value); + } +} + +void LiquidCrystal::pulseEnable(void) { + digitalWrite(_enable_pin, LOW); + delay(1); // Maple mod + //delayMicroseconds(1); + digitalWrite(_enable_pin, HIGH); + delay(1); // Maple mod + //delayMicroseconds(1); // enable pulse must be >450ns + digitalWrite(_enable_pin, LOW); + delay(1); // Maple mod + //delayMicroseconds(100); // commands need > 37us to settle +} + +void LiquidCrystal::write4bits(uint8 value) { + for (int i = 0; i < 4; i++) { + pinMode(_data_pins[i], OUTPUT); + digitalWrite(_data_pins[i], (value >> i) & 0x01); + } + + pulseEnable(); +} + +void LiquidCrystal::write8bits(uint8 value) { + for (int i = 0; i < 8; i++) { + pinMode(_data_pins[i], OUTPUT); + digitalWrite(_data_pins[i], (value >> i) & 0x01); + } + + pulseEnable(); +} diff --git a/libraries/LiquidCrystal/LiquidCrystal.h b/libraries/LiquidCrystal/LiquidCrystal.h new file mode 100644 index 0000000..0baf543 --- /dev/null +++ b/libraries/LiquidCrystal/LiquidCrystal.h @@ -0,0 +1,105 @@ +#ifndef LiquidCrystal_h +#define LiquidCrystal_h + +//#include <inttypes.h> +#include "wirish.h" +#include "Print.h" + +// commands +#define LCD_CLEARDISPLAY 0x01 +#define LCD_RETURNHOME 0x02 +#define LCD_ENTRYMODESET 0x04 +#define LCD_DISPLAYCONTROL 0x08 +#define LCD_CURSORSHIFT 0x10 +#define LCD_FUNCTIONSET 0x20 +#define LCD_SETCGRAMADDR 0x40 +#define LCD_SETDDRAMADDR 0x80 + +// flags for display entry mode +#define LCD_ENTRYRIGHT 0x00 +#define LCD_ENTRYLEFT 0x02 +#define LCD_ENTRYSHIFTINCREMENT 0x01 +#define LCD_ENTRYSHIFTDECREMENT 0x00 + +// flags for display on/off control +#define LCD_DISPLAYON 0x04 +#define LCD_DISPLAYOFF 0x00 +#define LCD_CURSORON 0x02 +#define LCD_CURSOROFF 0x00 +#define LCD_BLINKON 0x01 +#define LCD_BLINKOFF 0x00 + +// flags for display/cursor shift +#define LCD_DISPLAYMOVE 0x08 +#define LCD_CURSORMOVE 0x00 +#define LCD_MOVERIGHT 0x04 +#define LCD_MOVELEFT 0x00 + +// flags for function set +#define LCD_8BITMODE 0x10 +#define LCD_4BITMODE 0x00 +#define LCD_2LINE 0x08 +#define LCD_1LINE 0x00 +#define LCD_5x10DOTS 0x04 +#define LCD_5x8DOTS 0x00 + +class LiquidCrystal : public Print { +public: + LiquidCrystal(uint8 rs, uint8 enable, + uint8 d0, uint8 d1, uint8 d2, uint8 d3, + uint8 d4, uint8 d5, uint8 d6, uint8 d7); + LiquidCrystal(uint8 rs, uint8 rw, uint8 enable, + uint8 d0, uint8 d1, uint8 d2, uint8 d3, + uint8 d4, uint8 d5, uint8 d6, uint8 d7); + LiquidCrystal(uint8 rs, uint8 rw, uint8 enable, + uint8 d0, uint8 d1, uint8 d2, uint8 d3); + LiquidCrystal(uint8 rs, uint8 enable, + uint8 d0, uint8 d1, uint8 d2, uint8 d3); + + void init(uint8 fourbitmode, uint8 rs, uint8 rw, uint8 enable, + uint8 d0, uint8 d1, uint8 d2, uint8 d3, + uint8 d4, uint8 d5, uint8 d6, uint8 d7); + + void begin(uint8 cols, uint8 rows, uint8 charsize = LCD_5x8DOTS); + + void clear(); + void home(); + + void noDisplay(); + void display(); + void noBlink(); + void blink(); + void noCursor(); + void cursor(); + void scrollDisplayLeft(); + void scrollDisplayRight(); + void leftToRight(); + void rightToLeft(); + void autoscroll(); + void noAutoscroll(); + + void createChar(uint8, uint8[]); + void setCursor(uint8, uint8); + virtual void write(uint8); + void command(uint8); +private: + void send(uint8, uint8); + void write4bits(uint8); + void write8bits(uint8); + void pulseEnable(); + + uint8 _rs_pin; // LOW: command. HIGH: character. + uint8 _rw_pin; // LOW: write to LCD. HIGH: read from LCD. + uint8 _enable_pin; // activated by a HIGH pulse. + uint8 _data_pins[8]; + + uint8 _displayfunction; + uint8 _displaycontrol; + uint8 _displaymode; + + uint8 _initialized; + + uint8 _numlines,_currline; +}; + +#endif diff --git a/libraries/LiquidCrystal/rules.mk b/libraries/LiquidCrystal/rules.mk new file mode 100644 index 0000000..7b18203 --- /dev/null +++ b/libraries/LiquidCrystal/rules.mk @@ -0,0 +1,29 @@ +# Standard things +sp := $(sp).x +dirstack_$(sp) := $(d) +d := $(dir) +BUILDDIRS += $(BUILD_PATH)/$(d) + +# Local flags +CFLAGS_$(d) := $(WIRISH_INCLUDES) $(LIBMAPLE_INCLUDES) + +# Local rules and targets +cSRCS_$(d) := + +cppSRCS_$(d) := LiquidCrystal.cpp + +cFILES_$(d) := $(cSRCS_$(d):%=$(d)/%) +cppFILES_$(d) := $(cppSRCS_$(d):%=$(d)/%) + +OBJS_$(d) := $(cFILES_$(d):%.c=$(BUILD_PATH)/%.o) \ + $(cppFILES_$(d):%.cpp=$(BUILD_PATH)/%.o) +DEPS_$(d) := $(OBJS_$(d):%.o=%.d) + +$(OBJS_$(d)): TGT_CFLAGS := $(CFLAGS_$(d)) + +TGT_BIN += $(OBJS_$(d)) + +# Standard things +-include $(DEPS_$(d)) +d := $(dirstack_$(sp)) +sp := $(basename $(sp))
\ No newline at end of file diff --git a/libraries/Wire/README b/libraries/Wire/README new file mode 100644 index 0000000..353d51a --- /dev/null +++ b/libraries/Wire/README @@ -0,0 +1,5 @@ +Wirish soft (bit-banged) implementation of the Wire I2C library. + +This implementation is synchronous, and thus supports only a subset of +the full Wire interface. An asynchronous hardware version implemented +with DMA is expected for Maple IDE release 0.1.0. diff --git a/libraries/Wire/Wire.cpp b/libraries/Wire/Wire.cpp new file mode 100644 index 0000000..736bd25 --- /dev/null +++ b/libraries/Wire/Wire.cpp @@ -0,0 +1,259 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 LeafLabs LLC. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + *****************************************************************************/ + +/** + * @brief Wire library, ported from Arduino. Provides a simplistic + * interface to i2c. + */ + +#include "Wire.h" +#include "wirish.h" + +/* low level conventions: + * - SDA/SCL idle high (expected high) + * - always start with i2c_delay rather than end + */ +uint32 i2c_delay = 1; + +void i2c_start(Port port) { + I2C_DELAY; + digitalWrite(port.sda,LOW); + I2C_DELAY; + digitalWrite(port.scl,LOW); +} + +void i2c_stop(Port port) { + I2C_DELAY; + digitalWrite(port.scl,HIGH); + I2C_DELAY; + digitalWrite(port.sda,HIGH); +} + +boolean i2c_get_ack(Port port) { + I2C_DELAY; + digitalWrite(port.scl,LOW); + I2C_DELAY; + digitalWrite(port.sda,HIGH); + I2C_DELAY; + digitalWrite(port.scl,HIGH); + I2C_DELAY; + + if (!digitalRead(port.sda)) { + I2C_DELAY; + digitalWrite(port.scl,LOW); + return true; + } else { + I2C_DELAY; + digitalWrite(port.scl,LOW); + return false; + } +} + +void i2c_send_ack(Port port) { + I2C_DELAY; + digitalWrite(port.sda,LOW); + I2C_DELAY; + digitalWrite(port.scl,HIGH); + I2C_DELAY; + digitalWrite(port.scl,LOW); +} + +void i2c_send_nack(Port port) { + I2C_DELAY; + digitalWrite(port.sda,HIGH); + I2C_DELAY; + digitalWrite(port.scl,HIGH); +} + +uint8 i2c_shift_in(Port port) { + uint8 data = 0; + + int i; + for (i=0;i<8;i++) { + I2C_DELAY; + digitalWrite(port.scl,HIGH); + I2C_DELAY; + data += digitalRead(port.sda) << (7-i); + I2C_DELAY; + digitalWrite(port.scl,LOW); + } + + return data; +} + +void i2c_shift_out(Port port, uint8 val) { + int i; + for (i=0;i<8;i++) { + I2C_DELAY; + digitalWrite(port.sda, !!(val & (1 << (7 - i)))); + I2C_DELAY; + digitalWrite(port.scl, HIGH); + I2C_DELAY; + digitalWrite(port.scl, LOW); + } +} + +TwoWire::TwoWire() { + i2c_delay = 0; + rx_buf_idx = 0; + rx_buf_len = 0; + tx_addr = 0; + tx_buf_idx = 0; + tx_buf_overflow = false; +} + +/* + * Sets pins SDA and SCL to OUPTUT_OPEN_DRAIN, joining I2C bus as + * master. If you want them to be some other pins, use begin(uint8, + * uint8); + */ +void TwoWire::begin() { + begin(SDA, SCL); +} + +/* + * Joins I2C bus as master on given SDA and SCL pins. + */ +void TwoWire::begin(uint8 sda, uint8 scl) { + port.sda = sda; + port.scl = scl; + pinMode(scl, OUTPUT_OPEN_DRAIN); + pinMode(sda, OUTPUT_OPEN_DRAIN); + digitalWrite(scl, HIGH); + digitalWrite(sda, HIGH); +} + +void TwoWire::beginTransmission(uint8 slave_address) { + tx_addr = slave_address; + tx_buf_idx = 0; + tx_buf_overflow = false; + rx_buf_idx = 0; + rx_buf_len = 0; +} + +void TwoWire::beginTransmission(int slave_address) { + beginTransmission((uint8)slave_address); +} + +uint8 TwoWire::endTransmission(void) { + if (tx_buf_overflow) return EDATA; + + i2c_start(port); + + i2c_shift_out(port, (tx_addr << 1) | I2C_WRITE); + if (!i2c_get_ack(port)) return ENACKADDR; + + // shift out the address we're transmitting to + for (uint8 i = 0; i < tx_buf_idx; i++) { + uint8 ret = writeOneByte(tx_buf[i]); + if (ret) return ret; // SUCCESS is 0 + } + + i2c_stop(port); + + tx_buf_idx = 0; + tx_buf_overflow = false; + return SUCCESS; +} + +uint8 TwoWire::requestFrom(uint8 address, int num_bytes) { + if (num_bytes > WIRE_BUFSIZ) num_bytes = WIRE_BUFSIZ; + + rx_buf_idx = 0; + rx_buf_len = 0; + while (rx_buf_len < num_bytes) { + if(!readOneByte(address, rx_buf + rx_buf_len)) rx_buf_len++; + else break; + } + return rx_buf_len; +} + +uint8 TwoWire::requestFrom(int address, int numBytes) { + return TwoWire::requestFrom((uint8)address, (uint8) numBytes); +} + +void TwoWire::send(uint8 value) { + if (tx_buf_idx == WIRE_BUFSIZ) { + tx_buf_overflow = true; + return; + } + + tx_buf[tx_buf_idx++] = value; +} + +void TwoWire::send(uint8* buf, int len) { + for (uint8 i = 0; i < len; i++) send(buf[i]); +} + +void TwoWire::send(int value) { + send((uint8)value); +} + +void TwoWire::send(int* buf, int len) { + send((uint8*)buf, (uint8)len); +} + +void TwoWire::send(char* buf) { + uint8 *ptr = (uint8*)buf; + while(*ptr) { + send(*ptr); + ptr++; + } +} + +uint8 TwoWire::available() { + return rx_buf_len - rx_buf_idx; +} + +uint8 TwoWire::receive() { + if (rx_buf_idx == rx_buf_len) return 0; + return rx_buf[rx_buf_idx++]; +} + +// private methods + +uint8 TwoWire::writeOneByte(uint8 byte) { + i2c_shift_out(port, byte); + if (!i2c_get_ack(port)) return ENACKTRNS; + + return SUCCESS; +} + +uint8 TwoWire::readOneByte(uint8 address, uint8 *byte) { + i2c_start(port); + + i2c_shift_out(port, (address << 1) | I2C_READ); + if (!i2c_get_ack(port)) return ENACKADDR; + + *byte = i2c_shift_in(port); + + i2c_send_nack(port); + i2c_stop(port); + + return SUCCESS; // no real way of knowing, but be optimistic! +} + +// Declare the instance that the users of the library can use +TwoWire Wire; + diff --git a/libraries/Wire/Wire.h b/libraries/Wire/Wire.h new file mode 100644 index 0000000..62e37bd --- /dev/null +++ b/libraries/Wire/Wire.h @@ -0,0 +1,99 @@ +/* ***************************************************************************** + * The MIT License + * + * Copyright (c) 2010 LeafLabs LLC. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * ****************************************************************************/ + +/** + * @brief Wire library, ported from Arduino. Provides a lean + * interface to I2C (two-wire) communication. + */ + +#include "wirish.h" + +#ifndef _WIRE_H_ +#define _WIRE_H_ + +typedef struct { + uint8 scl; + uint8 sda; +} Port; + +/* You must update the online docs if you change this value. */ +#define WIRE_BUFSIZ 32 + +/* return codes from endTransmission() */ +#define SUCCESS 0 /* transmission was successful */ +#define EDATA 1 /* too much data */ +#define ENACKADDR 2 /* received nack on transmit of address */ +#define ENACKTRNS 3 /* received nack on transmit of data */ +#define EOTHER 4 /* other error */ + +#define SDA 20 +#define SCL 21 + +#define I2C_WRITE 0 +#define I2C_READ 1 + +#define I2C_DELAY do{for(int i=0;i<50;i++) {asm volatile("nop");}}while(0) + +class TwoWire { + private: + uint8 rx_buf[WIRE_BUFSIZ]; /* receive buffer */ + uint8 rx_buf_idx; /* first unread idx in rx_buf */ + uint8 rx_buf_len; /* number of bytes read */ + + uint8 tx_addr; /* address transmitting to */ + uint8 tx_buf[WIRE_BUFSIZ]; /* transmit buffer */ + uint8 tx_buf_idx; /* next idx available in tx_buf, -1 overflow */ + boolean tx_buf_overflow; + Port port; + uint8 writeOneByte(uint8); + uint8 readOneByte(uint8, uint8*); + public: + TwoWire(); + void begin(); + void begin(uint8, uint8); + void beginTransmission(uint8); + void beginTransmission(int); + uint8 endTransmission(void); + uint8 requestFrom(uint8, int); + uint8 requestFrom(int, int); + void send(uint8); + void send(uint8*, int); + void send(int); + void send(int*, int); + void send(char*); + uint8 available(); + uint8 receive(); +}; + +void i2c_start(Port port); +void i2c_stop(Port port); +boolean i2c_get_ack(Port port); +void i2c_send_ack(Port port); +void i2c_send_nack(Port port); +uint8 i2c_shift_in(Port port); +void i2c_shift_out(Port port, uint8 val); + +extern TwoWire Wire; + +#endif // _WIRE_H_ diff --git a/libraries/Wire/rules.mk b/libraries/Wire/rules.mk new file mode 100644 index 0000000..71f5e75 --- /dev/null +++ b/libraries/Wire/rules.mk @@ -0,0 +1,29 @@ +# Standard things +sp := $(sp).x +dirstack_$(sp) := $(d) +d := $(dir) +BUILDDIRS += $(BUILD_PATH)/$(d) + +# Local flags +CFLAGS_$(d) := $(WIRISH_INCLUDES) $(LIBMAPLE_INCLUDES) + +# Local rules and targets +cSRCS_$(d) := + +cppSRCS_$(d) := Wire.cpp + +cFILES_$(d) := $(cSRCS_$(d):%=$(d)/%) +cppFILES_$(d) := $(cppSRCS_$(d):%=$(d)/%) + +OBJS_$(d) := $(cFILES_$(d):%.c=$(BUILD_PATH)/%.o) \ + $(cppFILES_$(d):%.cpp=$(BUILD_PATH)/%.o) +DEPS_$(d) := $(OBJS_$(d):%.o=%.d) + +$(OBJS_$(d)): TGT_CFLAGS := $(CFLAGS_$(d)) + +TGT_BIN += $(OBJS_$(d)) + +# Standard things +-include $(DEPS_$(d)) +d := $(dirstack_$(sp)) +sp := $(basename $(sp))
\ No newline at end of file diff --git a/main.cpp.example b/main.cpp.example index 1032733..8fc522a 100644 --- a/main.cpp.example +++ b/main.cpp.example @@ -1,15 +1,17 @@ -// Sample main.cpp file. Blinks an LED, sends a message out USART2 -// and turns on PWM on pin 2 +// Sample main.cpp file. Blinks the built-in LED, sends a message out +// USART2, and turns on PWM on pin 2. #include "wirish.h" -#define LED_PIN 13 #define PWM_PIN 2 -void setup() -{ +void setup() { /* Set up the LED to blink */ - pinMode(LED_PIN, OUTPUT); + pinMode(BOARD_LED_PIN, OUTPUT); + + /* Turn on PWM on pin PWM_PIN */ + pinMode(PWM_PIN, PWM); + pwmWrite(PWM_PIN, 0x8000); /* Send a message out USART2 */ Serial2.begin(9600); @@ -17,28 +19,20 @@ void setup() /* Send a message out the usb virtual serial port */ SerialUSB.println("Hello!"); - - /* Turn on PWM on pin PWM_PIN */ - pinMode(PWM_PIN, PWM); - pwmWrite(PWM_PIN, 0x8000); } -int toggle = 0; - void loop() { - toggle ^= 1; - digitalWrite(LED_PIN, toggle); + toggleLED(); delay(100); } // Force init to be called *first*, i.e. before static object allocation. // Otherwise, statically allocated object that need libmaple may fail. - __attribute__(( constructor )) void premain() { +__attribute__(( constructor )) void premain() { init(); } -int main(void) -{ +int main(void) { setup(); while (1) { diff --git a/notes/coding_standard.txt b/notes/coding_standard.txt index c0e4e4e..5cb96c3 100644 --- a/notes/coding_standard.txt +++ b/notes/coding_standard.txt @@ -1,21 +1,31 @@ -Source code standards for libmaple. +libmaple Coding Standards +========================= -Do it like this unless there's a really good reason why not. You -being a lazy bastard doesn't count as a good reason. +Author: Marti Bolivar (mbolivar@leaflabs.com) + +LeafLabs team members are required to follow these when producing new +code. Community contributors to libmaple are strongly encouraged to +do so; following these rules will greatly increase the probability +that your patches will be folded in. + +In general, do it like this unless there's a really good reason why +not. You being lazy doesn't count as a good reason. Most, if not +all, of these decisions are entirely arbitrary, but it's important for +readability that we be consistent. The file .dir-locals.el in the libmaple root directory already ensures -that many of these standards are followed by default, if you use emacs -(and not Windows, where it would need to be named _dir_locals.el, and -no way, man). There's also some elisp scattered about this file which +that many of these standards are followed by default in Emacs (but not +on Windows, where it would need to be named _dir_locals.el, and no +way, man). There's also some elisp scattered about this file which will provide you additional help. -Vim customizations to do the same thing would be nice! +Vim customizations to do the same thing would be nice (hint, hint)! License ------- - Put an MIT license at the beginning of the file (look at any of our - source files for an example). Copyright should go to either your or + source files for an example). Copyright should go to either you or LeafLabs LLC. Emacs: if you don't like seeing the license, you should use @@ -31,8 +41,8 @@ License (dolist (hook mbolivar-programming-mode-hooks) (add-hook hook (lambda () (elide-head)))) -Whitespace ----------- +Whitespace/Indentation +---------------------- - 4 space indents. [Set in .dir-locals.el] @@ -45,17 +55,28 @@ Whitespace http://github.com/mbolivar/code-fascism - I hear tell you can get something similar in vim; ask Perry, I + I hear tell you can get something similar in vim; ask around, I guess. - Files end in exactly one newline. [The presence of a newline at EOF is already done by `c-require-final-newline' in recent versions of Emacs.] -- Exactly two newlines separate source paragraphs. +- Exactly two newlines separate source paragraphs (you do separate + your code into paragraphs, don't you?). - The first line in a function is non-blank. +- Don't indent C code within a conditionally-compiled extern "C" + block. Emacs does this by default, which can be very annoying; you + can turn this behavior off with + + (defun c-mode-inextern-lang-hook () + (setcdr (assq 'inextern-lang c-offsets-alist) '-)) + + (add-hook 'c-mode-hook c-mode-inextern-lang-hook) + + Comments -------- @@ -71,7 +92,8 @@ Comments /* comment starts here * the comment can end on the same line */ -- Doxygen comments begin with /** instead. +- Doxygen comments are newline comments that begin with /** instead. + It is not required that the "/**" appear on a line by itself. - Single-line comments on the same line are // in c or c++. @@ -94,9 +116,13 @@ Braces Naming conventions ------------------ -So there's always a fight about upper and lower case vs. underscores. -We'll handle this as follows. First, Dammit_Dont_Mix_Like_This, -because It_Looks_Really_Ugly, ok? +- There's always a fight about upper and lower case vs. underscores. + We'll handle this as follows. + + First, Dammit_Dont_Mix_Like_This, because It_Looks_Really_Ugly, ok? + [There's been some debate about this, and some exceptions are + already grandfathered in, so in order to settle it, let's call this + a "recommendation" instead of "requirement".] - Variables: Use underscores to separate words in C identifiers: @@ -109,7 +135,7 @@ because It_Looks_Really_Ugly, ok? this_is_not, and like I said, Dont_You_DareTryANYTHING_STUPID. - Functions: C functions are all lowercase, and words are separated by - underscores. C++ method names are camel cased. + underscores. C++ method names are camel cased (thisIsAnExample). - Structs: pick a style from "Variables" or "Classes" depending on how you mean it (since it might be either a simple record type, in which @@ -117,8 +143,16 @@ because It_Looks_Really_Ugly, ok? which case do like classes). If it's in a typedef, don't feel obliged to put "_t" at the end of the name; we don't. +- Macros and constants: all caps, separated by underscores. Variables + with the "const" qualifier aren't considered "constants" for the + purposes of this rule; i.e., case them according to the rules for + variables. + +- foo.h gets #ifdef'ed to _FOO_H_. + - Acronyms: The case of letters in an acronym is determined by the - case of the first letter in the acronym. Examples: + case of the first letter in the acronym, which is determined by + following the above rules. Examples: void usb_func() { ... } @@ -127,21 +161,28 @@ because It_Looks_Really_Ugly, ok? void initUSB(); }; - NEVER DO THIS: + Never do this: class BadUsb { ... }; // say "GoodUSB" instead -- Macros and constants: all caps, separated by underscores. - -- foo.h gets ifdef'ed to _FOO_H_. - Documentation ------------- - Document your code. This should go without saying. -- At least put a doxygen comment with a nonempty @brief for every - source file you add. See the existing ones for examples. +- For complicated peripherals, it would be nice if you put longer-form + comments into this directory (notes/), with a comment in the + corresponding .h file referring to it. See libmaple/dac.h for an + example. That lets us keep the source files relatively clean while + still allowing new readers to have a starting point. + +- At least put a doxygen comment with a nonempty @brief for every .h + file you add. See the existing ones for examples. For now, it'd be + better if you didn't put a @brief into any .c[pp] files, since it + (currently) interferes with our documentation generator in a way + that I won't explain here (though you can look into the LeafLabs or + michaeljones breathe repos on github and potentially figure out + why). - Doxygen comments generally just belong on types, functions, etc. that are part of the public user-facing API. This generally @@ -171,7 +212,7 @@ General Formatting http://www.helsinki.fi/~sjpaavol/programs/lineker.el - Then put the file somewhere in your load-path, and + Then put the file somewhere in your load-path, and: (require 'lineker) (dolist (hook '(c-mode-hook c++-mode-hook)) diff --git a/notes/native-pin-definitions.txt b/notes/native-pin-definitions.txt new file mode 100644 index 0000000..b871f89 --- /dev/null +++ b/notes/native-pin-definitions.txt @@ -0,0 +1,201 @@ +Maple Native (STM32F103ZE) pin definitions, by GPIO bank. + +Source: ST DOC ID 14611, Datasheet for STM32F103xC, STM32F103xD, +STM32F103xE, Table 5, pp. 30--35. + +Some peripherals and extra functionality with less/no libmaple +relevance (at time of writing) are given in "Other" following each +bank's main table. Non-default alternate functions are not listed. If +wirish will/does remap the pin's main function after reset, the main +function is listed under "Other". + +This document was prepared carefully and is believed to be complete +and correct, but the final arbiter of truth is the ST datasheet. + +*** NB: UART 4 and 5 are NOT USART (columns are labeled appropriately). + +--------------------------------------------------------------------------- +STM32 ADC Timer FSMC I2S I2C USART SPI DAC 5v? +--------------------------------------------------------------------------- +PA0 123in0 2ch1etr - - - 2cts - - - + 5ch1 + 8etr +PA1 123in1 5ch2 - - - 2rts - - - + 2ch2 +PA2 123in2 5ch3 - - - 2tx - - - + 2ch3 +PA3 123in3 5ch4 - - - 2rx - - - + 2ch4 +PA4 12in4 - - - - 2ck 1nss out1 - +PA5 12in5 - - - - - 1sck out2 - +PA6 12in6 8bkin - - - - 1miso - - + 3ch1 +PA7 12in7 8ch1n - - - - 1mosi - - + 3ch2 +PA8 - 1ch1 - - - 1ck - - Y +PA9 - 1ch2 - - - 1tx - - Y +PA10 - 1ch3 - - - 1rx - - Y +PA11 - 1ch4 - - - 1cts - - Y +PA12 - 1etr - - - 1rts - - Y +PA13 - - - - - - - - Y +PA14 - - - - - - - - Y +PA15 - - - 3ws - - 3nss - Y + +Other: + +PA0: WKUP +PA8: MCO +PA11: USBDM, CAN_RX +PA12: USBDP, CAN_TX +PA13: JTMS-SWDIO (default) +PA14: JTCK-SWCLK (default) +PA15: JTDI (default) + +------------------------------------------------------------------------------- +STM32 ADC Timer FSMC I2S I2C USART SPI DAC 5v? SDIO +------------------------------------------------------------------------------- +PB0 12in8 3ch3 - - - - - - - - + 8ch2n +PB1 12in9 3ch4 - - - - - - - - + 8ch3n +PB2 - - - - - - - - Y - +PB3 - - - 3ck - - 3sck - Y - +PB4 - - - - - - 3miso - Y - +PB5 - - - 3sd 1smba - 3mosi - - - +PB6 - 4ch1 - - 1scl - - - Y - +PB7 - 4ch2 NADV - 1sda - - - Y - +PB8 - 4ch3 - - - - - - Y D4 +PB9 - 4ch4 - - - - - - Y D5 +PB10 - - - - 2scl 3tx - - Y - +PB11 - - - - 2sda 3rx - - Y - +PB12 - 1bkin - 2ws 2smba 3ck 2nss - Y - +PB13 - 1ch1n - 2ck - 3cts 2sck - Y - +PB14 - 1ch2n - - - 3rts 2miso - Y - +PB15 - 1ch3n - 2sd - - 2mosi - Y - + +Other: + +PB2: BOOT1 +PB3: JTDO (default) +PB4: NJTRST (default) + +------------------------------------------------------------------------------- +STM32 ADC Timer FSMC I2S I2C UART SPI DAC 5v? SDIO +------------------------------------------------------------------------------- +PC0 123in10 - - - - - - - - - +PC1 123in11 - - - - - - - - - +PC2 123in12 - - - - - - - - - +PC3 123in13 - - - - - - - - - +PC4 12in14 - - - - - - - - - +PC5 12in15 - - - - - - - - - +PC6 - 8ch1 - 2mck - - - - Y D6 +PC7 - 8ch2 - 3mck - - - - Y D7 +PC8 - 8ch3 - - - - - - Y D0 +PC9 - 8ch4 - - - - - - Y D1 +PC10 - - - - - 4tx - - Y D2 +PC11 - - - - - 4rx - - Y D3 +PC12 - - - - - 5tx - - Y CK +PC13 - - - - - - - - - - +PC14 - - - - - - - - - - +PC15 - - - - - - - - - - + +Other: + +PC13: TAMPER_RTC +PC14: OSC32_IN +PC15: OSC32_OUT + +------------------------------------------------------------------------------- +STM32 ADC Timer FSMC I2S I2C UART SPI DAC 5v? SDIO +------------------------------------------------------------------------------- +PD0 - - D2 - - - - - Y - +PD1 - - D3 - - - - - Y - +PD2 - 3etr - - - 5rx - - Y CMD +PD3 - - CLK - - - - - Y - +PD4 - - NOE - - - - - Y - +PD5 - - NWE - - - - - Y - +PD6 - - NWAIT - - - - - Y - +PD7 - - NE1 - - - - - Y - + NCE2 +PD8 - - D13 - - - - - Y - +PD9 - - D14 - - - - - Y - +PD10 - - D15 - - - - - Y - +PD11 - - A16 - - - - - Y - +PD12 - - A17 - - - - - Y - +PD13 - - A18 - - - - - Y - +PD14 - - D0 - - - - - Y - +PD15 - - D1 - - - - - Y - + +Other: + +PD0: OSC_IN (default) +PD1: OSC_OUT (default) + +--------------------------------------------------------------------------- +STM32 ADC Timer FSMC I2S I2C USART SPI DAC 5v? +--------------------------------------------------------------------------- +PE0 - 4etr NBL0 - - - - - Y +PE1 - - NBL1 - - - - - Y +PE2 - - A23 - - - - - Y +PE3 - - A19 - - - - - Y +PE4 - - A20 - - - - - Y +PE5 - - A21 - - - - - Y +PE6 - - A22 - - - - - Y +PE7 - - D4 - - - - - Y +PE8 - - D5 - - - - - Y +PE9 - - D6 - - - - - Y +PE10 - - D7 - - - - - Y +PE11 - - D8 - - - - - Y +PE12 - - D9 - - - - - Y +PE13 - - D10 - - - - - Y +PE14 - - D11 - - - - - Y +PE15 - - D12 - - - - - Y + +Other: +PE2: TRACECK +PE3: TRACED0 +PE4: TRACED1 +PE5: TRACED2 +PE6: TRACED3 + +--------------------------------------------------------------------------- +STM32 ADC Timer FSMC I2S I2C USART SPI DAC 5v? +--------------------------------------------------------------------------- +PF0 - - A0 - - - - - Y +PF1 - - A1 - - - - - Y +PF2 - - A2 - - - - - Y +PF3 - - A3 - - - - - Y +PF4 - - A4 - - - - - Y +PF5 - - A5 - - - - - Y +PF6 3in4 - NIORD - - - - - - +PF7 3in5 - NREG - - - - - - +PF8 3in6 - NIOWR - - - - - - +PF9 3in7 - CD - - - - - - +PF10 3in8 - INTR - - - - - - +PF11 - - NIOS16 - - - - - Y +PF12 - - A6 - - - - - Y +PF13 - - A7 - - - - - Y +PF14 - - A8 - - - - - Y +PF15 - - A9 - - - - - Y + +--------------------------------------------------------------------------- +STM32 ADC Timer FSMC I2S I2C USART SPI DAC 5v? +--------------------------------------------------------------------------- +PG0 - - A10 - - - - - Y +PG1 - - A11 - - - - - Y +PG2 - - A12 - - - - - Y +PG3 - - A13 - - - - - Y +PG4 - - A14 - - - - - Y +PG5 - - A15 - - - - - Y +PG6 - - INT2 - - - - - Y +PG7 - - INT3 - - - - - Y +PG8 - - - - - - - - Y +PG9 - - NE2 - - - - - Y + NCE3 +PG10 - - NCE4_1 - - - - - Y + NE3 +PG11 - - NCE4_2 - - - - - Y +PG12 - - NE4 - - - - - Y +PG13 - - A24 - - - - - Y +PG14 - - A25 - - - - - Y +PG15 - - - - - - - - Y diff --git a/notes/pin-mapping.txt b/notes/pin-mapping.txt index 67a675c..24402ed 100644 --- a/notes/pin-mapping.txt +++ b/notes/pin-mapping.txt @@ -1,3 +1,11 @@ +The pin maps in this document are included for informational purposes +only. The final arbiters of truth are the PIN_MAP definitions in +../wirish/boards.h and the STM32 datasheets. + +==== +Maple +==== + Reserved Pins: Function PA11 USBDM PA12 USBDP @@ -13,8 +21,12 @@ PC12 DISC PD0 OSC_IN PD1 OSC_OUT +Alternate function remaps: + +None? + ------------------------------------------------------------------------------- -Pin STM32 PIN ADC Timer I2C UART SPI F/T +Pin STM32 PIN ADC Timer I2C UART SPI 5v? ------------------------------------------------------------------------------- D0 PA3 ADC3 TIM2_CH4 - USART2_RX - - D1 PA2 ADC2 TIM2_CH3 - USART2_TX - - @@ -64,7 +76,88 @@ D37 PC8 - - - - - Y Note: former pin D38 (PC9) is now attached to the BUT button and there is a GND connection where D38 was. -todo: -adc pin check -jtag pins for gpio +TODO: +- [?] JTAG pins for GPIO + +========== +Maple Mini +========== + +Reserved pins: + +Pin Function +--- -------- +PA11 USBDM +PA12 USBDP +PB8 BUT button +PB9 DISC +PD0 OSC_IN +PD1 OSC_OUT + +Alternate function remaps: + +Pin Default Remap +--- ------- ----- +PB4 JNTRST GPIO +PB3 JTDO GPIO +PA15 JTDI GPIO +PA14 JTCK GPIO +PA13 JTMS GPIO + +------------------------------------------------------------------------------- +Pin STM32 PIN ADC Timer I2C USART SPI 5v? +------------------------------------------------------------------------------- +D0 PB11 - - I2C2_SDA USART3_RX - Y +D1 PB10 - - I2C2_SCL USART3_TX - Y +D2 PB2 - - - - - Y +D3 PB0 ADC8 TIM3_CH3 - - - - +D4 PA7 ADC7 TIM3_CH2 - - SPI1_MOSI - +D5 PA6 ADC6 TIM3_CH1 - - SPI1_MISO - +D6 PA5 ADC5 - - - SPI1_SCK - +D7 PA4 ADC4 - - USART2_CK SPI1_NSS - +D8 PA3 ADC3 TIM2_CH4 - USART2_RX - - +D9 PA2 ADC2 TIM2_CH3 - USART2_TX - - +D10 PA1 ADC1 TIM2_CH2 - USART2_RTS - - +D11 PA0 ADC0 TIM2_CH1_ETR - USART2_CTS - - +D12 PC15 - - - - - - +D13 PC14 - - - - - - +D14 PC13 - - - - - - +D15 PB7 - TIM4_CH2 I2C1_SDA - - Y +D16 PB6 - TIM4_CH1 I2C1_SCL - - Y +D17 PB5 - - I2C1_SMBA - - - +D18 PB4 - - - - - Y +D19 PB3 - - - - - Y +D20 PA15 - - - - - Y +D21 PA14 - - - - - Y +D22 PA13 - - - - - Y +# D23 is USBDP, but supports: + PA12 - - - - - Y +# D24 is USBDM, but supports: + PA11 - - - - - Y +D25 PA10 - TIM1_CH3 - USART1_RX - Y +D26 PA9 - TIM1_CH2 - USART1_TX - Y +D27 PA8 - TIM1_CH1 - USART1_CK - Y +D28 PB15 - TIM1_CH3N - - SPI2_MOSI Y +D29 PB14 - TIM1_CH2N - USART3_RTS SPI2_MISO Y +D30 PB13 - TIM1_CH1N - USART3_CTS SPI2_SCK Y +D31 PB12 - TIM1_BKIN I2C2_SMBAL USART3_CK SPI2_NSS Y +D32 PB8 0 TIM4_CH3 - - - Y +D33 PB1 ADC9 TIM3_CH4 - - - - + +TODO: +- [?] JTAG pins for GPIO + +============ +Maple Native +============ + +Reserved pins: + +TODO + +Alternate function remaps: + +TODO +The pin map on Maple Native is in flux. However, the bank/port pin +definitions are available in notes/native-pin-definitions.txt. diff --git a/support/ld/maple_native/flash.ld b/support/ld/maple_native/flash.ld index 7e1e453..4e820d2 100644 --- a/support/ld/maple_native/flash.ld +++ b/support/ld/maple_native/flash.ld @@ -26,7 +26,7 @@ MEMORY
{
ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 61K
- rom (rx) : ORIGIN = 0x08005000, LENGTH = 500K
+ rom (rx) : ORIGIN = 0x08005000, LENGTH = 492K
}
OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
diff --git a/support/ld/maple_native/jtag.ld b/support/ld/maple_native/jtag.ld index 85aae53..90a0a3f 100644 --- a/support/ld/maple_native/jtag.ld +++ b/support/ld/maple_native/jtag.ld @@ -8,8 +8,8 @@ /* Define memory spaces. */
MEMORY
{
- ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 61K
- rom (rx) : ORIGIN = 0x08005000, LENGTH = 500K
+ ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K
+ rom (rx) : ORIGIN = 0x08000000, LENGTH = 512K
}
OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
diff --git a/support/openocd/flash_0.4.0.cfg b/support/openocd/flash_0.4.0.cfg new file mode 100644 index 0000000..e66d28d --- /dev/null +++ b/support/openocd/flash_0.4.0.cfg @@ -0,0 +1,89 @@ +# script for stm32 + +interface ft2232 +ft2232_device_desc "Olimex OpenOCD JTAG" +ft2232_layout olimex-jtag +ft2232_vid_pid 0x15ba 0x0003 + +if { [info exists CHIPNAME] } { + set _CHIPNAME $CHIPNAME +} else { + set _CHIPNAME stm32 +} + +if { [info exists ENDIAN] } { + set _ENDIAN $ENDIAN +} else { + set _ENDIAN little +} + +# jtag speed speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so ufse F_JTAG = 1MHz +jtag_khz 1000 + +jtag_nsrst_delay 100 +jtag_ntrst_delay 100 + +#use combined on interfaces or targets that can't set TRST/SRST separately +reset_config trst_and_srst + +#jtag scan chain +if { [info exists CPUTAPID ] } { + set _CPUTAPID $CPUTAPID +} else { + # See STM Document RM0008 + # Section 30.6.3 + set _CPUTAPID 0x3ba00477 +} + +jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID + +if { [info exists BSTAPID ] } { + # FIXME this never gets used to override defaults... + set _BSTAPID $BSTAPID +} else { + # See STM Document RM0008 + # Section 29.6.2 + # Low density devices, Rev A + set _BSTAPID1 0x06412041 + # Medium density devices, Rev A + set _BSTAPID2 0x06410041 + # Medium density devices, Rev B and Rev Z + set _BSTAPID3 0x16410041 + # High density devices, Rev A + set _BSTAPID4 0x06414041 + # Connectivity line devices, Rev A and Rev Z + set _BSTAPID5 0x06418041 +} +jtag newtap $_CHIPNAME bs -irlen 5 -expected-id $_BSTAPID1 \ + -expected-id $_BSTAPID2 -expected-id $_BSTAPID3 \ + -expected-id $_BSTAPID4 -expected-id $_BSTAPID5 + + +set _TARGETNAME $_CHIPNAME.cpu +target create $_TARGETNAME cortex_m3 -endian $_ENDIAN -chain-position $_TARGETNAME + +$_TARGETNAME configure -work-area-virt 0 -work-area-phys 0x20000000 -work-area-size 0x5000 -work-area-backup 0 +# TODO: native +#$_TARGETNAME configure -work-area-virt 0 -work-area-phys 0x20000000 -work-area-size 0x10000 -work-area-backup 0 + +flash bank bank0 stm32x 0x08000000 0x00020000 0 0 $_TARGETNAME + +proc flash_chip {} { + echo "Halting..." + halt + echo "Erasing..." + flash erase_address 0x08000000 0x20000 + # TODO: native + #flash erase_address 0x08000000 0x80000 + echo "Flashing image..." + flash write_bank 0 build/maple.bin 0 + echo "Verifying image..." + verify_image build/maple.bin 0x08000000 bin + echo "Checksum verified, resetting chip" + reset run + echo "Daemon shutdown" + shutdown +} + +init +flash_chip diff --git a/support/openocd/run_0.4.0.cfg b/support/openocd/run_0.4.0.cfg new file mode 100644 index 0000000..bbc8864 --- /dev/null +++ b/support/openocd/run_0.4.0.cfg @@ -0,0 +1,75 @@ +# script for stm32 + +interface ft2232 +ft2232_device_desc "Olimex OpenOCD JTAG" +ft2232_layout olimex-jtag +ft2232_vid_pid 0x15ba 0x0003 + +if { [info exists CHIPNAME] } { + set _CHIPNAME $CHIPNAME +} else { + set _CHIPNAME stm32 +} + +if { [info exists ENDIAN] } { + set _ENDIAN $ENDIAN +} else { + set _ENDIAN little +} + +# jtag speed speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so ufse F_JTAG = 1MHz +jtag_khz 1000 + +jtag_nsrst_delay 100 +jtag_ntrst_delay 100 + +#use combined on interfaces or targets that can't set TRST/SRST separately +reset_config trst_and_srst + +#jtag scan chain +if { [info exists CPUTAPID ] } { + set _CPUTAPID $CPUTAPID +} else { + # See STM Document RM0008 + # Section 30.6.3 + set _CPUTAPID 0x3ba00477 +} + +jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID + +if { [info exists BSTAPID ] } { + # FIXME this never gets used to override defaults... + set _BSTAPID $BSTAPID +} else { + # See STM Document RM0008 + # Section 29.6.2 + # Low density devices, Rev A + set _BSTAPID1 0x06412041 + # Medium density devices, Rev A + set _BSTAPID2 0x06410041 + # Medium density devices, Rev B and Rev Z + set _BSTAPID3 0x16410041 + # High density devices, Rev A + set _BSTAPID4 0x06414041 + # Connectivity line devices, Rev A and Rev Z + set _BSTAPID5 0x06418041 +} +jtag newtap $_CHIPNAME bs -irlen 5 -expected-id $_BSTAPID1 \ + -expected-id $_BSTAPID2 -expected-id $_BSTAPID3 \ + -expected-id $_BSTAPID4 -expected-id $_BSTAPID5 + + +set _TARGETNAME $_CHIPNAME.cpu +target create $_TARGETNAME cortex_m3 -endian $_ENDIAN -chain-position $_TARGETNAME + +$_TARGETNAME configure -work-area-virt 0 -work-area-phys 0x20000000 -work-area-size 0x5000 -work-area-backup 0 + +flash bank bank0 stm32x 0x08000000 0x00020000 0 0 $_TARGETNAME + +proc nopforever {} { + puts "Resetting the chip..." + reset run +} + +init +nopforever diff --git a/support/scripts/copy-to-ide b/support/scripts/copy-to-ide index 6f8d5f3..301126d 100755 --- a/support/scripts/copy-to-ide +++ b/support/scripts/copy-to-ide @@ -7,6 +7,7 @@ DEST=$1 DEST_REF=$DEST/build/shared/reference DEST_CORES=$DEST/hardware/leaflabs/cores/maple +DEST_LIBS=$DEST/libraries LMAPLE_SRC="LICENSE ./libmaple/*.h @@ -38,19 +39,22 @@ then fi # source -echo Handling libmaple source -rm -r $DEST_CORES/*.c $DEST_CORES/*.cpp $DEST_CORES/*.h $DEST_CORES/*.cxx $DEST_CORES/*.inc $DEST_CORES/*.a $DEST_CORES/*.S $DEST_CORES/maple $DEST_CORES/maple_native +echo Copying libmaple source +rm -rf $DEST_CORES/*.c $DEST_CORES/*.cpp $DEST_CORES/*.h $DEST_CORES/*.cxx $DEST_CORES/*.inc $DEST_CORES/*.a $DEST_CORES/*.S $DEST_CORES/maple $DEST_CORES/maple_native cp -R $LMAPLE_SRC $DEST_CORES +echo Copying over libraries +cp -R libraries/* $DEST_LIBS + # docs echo Deleting old reference directory contents -rm -r $DEST_REF/* +rm -rf $DEST_REF/* -# echo "\nRebuilding documentation" -# (cd $LMAPLE_DOCS; doxygen 2>/dev/null 1>/dev/null && make clean 2>/dev/null 1>/dev/null && make html 2>&1 1>/dev/null) +echo Rebuilding documentation +( cd $LMAPLE_DOCS; doxygen && make clean 2>/dev/null 1>/dev/null && make html ) echo Copying over documentation cp -R $LMAPLE_DOCS_BUILD/* $DEST_REF -echo -echo "Done. Handle libraries manually!" + +echo Done. diff --git a/wirish/boards.h b/wirish/boards.h index 84ff44f..f8505ab 100644 --- a/wirish/boards.h +++ b/wirish/boards.h @@ -161,7 +161,7 @@ typedef struct PinMapping { {GPIOC_BASE, 7, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, /* D37/PC8 */ {GPIOC_BASE, 8, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, - /* PC9 (BUT) */ + /* D38/PC9 (BUT) */ {GPIOC_BASE, 9, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID} }; @@ -175,125 +175,223 @@ typedef struct PinMapping { #define CYCLES_PER_MICROSECOND 72 #define SYSTICK_RELOAD_VAL 71999 /* takes a cycle to reload */ - // TODO: - static __attribute__ ((unused)) PinMapping PIN_MAP[NR_GPIO_PINS] = { - /* D0/PA3 */ - {GPIOA_BASE, 3, ADC3, TIMER2_CH4_CCR}, - /* D1/PA2 */ - {GPIOA_BASE, 2, ADC2, TIMER2_CH3_CCR}, - /* D2/PA0 */ - {GPIOA_BASE, 0, ADC0, TIMER2_CH1_CCR}, - /* D3/PA1 */ - {GPIOA_BASE, 1, ADC1, TIMER2_CH2_CCR}, - /* D4/PB5 */ - {GPIOB_BASE, 5, ADC_INVALID, TIMER_INVALID}, - /* D5/PB6 */ - {GPIOB_BASE, 6, ADC_INVALID, TIMER4_CH1_CCR}, - /* D6/PA8 */ - {GPIOA_BASE, 8, ADC_INVALID, TIMER1_CH1_CCR}, - /* D7/PA9 */ - {GPIOA_BASE, 9, ADC_INVALID, TIMER1_CH2_CCR}, - /* D8/PA10 */ - {GPIOA_BASE, 10, ADC_INVALID, TIMER1_CH3_CCR}, - /* D9/PB7 */ - {GPIOB_BASE, 7, ADC_INVALID, TIMER4_CH2_CCR}, - /* D10/PA4 */ - {GPIOA_BASE, 4, ADC4, TIMER_INVALID}, - /* D11/PA7 */ - {GPIOA_BASE, 7, ADC7, TIMER3_CH2_CCR}, - /* D12/PA6 */ - {GPIOA_BASE, 6, ADC6, TIMER3_CH1_CCR}, - /* D13/PA5 */ - {GPIOA_BASE, 5, ADC5, TIMER_INVALID}, - /* D14/PB8 */ - {GPIOB_BASE, 8, ADC_INVALID, TIMER4_CH3_CCR}, - - /* Little header */ - - /* D15/PC0 */ - {GPIOC_BASE, 0, ADC10, TIMER_INVALID}, - /* D16/PC1 */ - {GPIOC_BASE, 1, ADC11, TIMER_INVALID}, - /* D17/PC2 */ - {GPIOC_BASE, 2, ADC12, TIMER_INVALID}, - /* D18/PC3 */ - {GPIOC_BASE, 3, ADC13, TIMER_INVALID}, - /* D19/PC4 */ - {GPIOC_BASE, 4, ADC14, TIMER_INVALID}, - /* D20/PC5 */ - {GPIOC_BASE, 5, ADC15, TIMER_INVALID}, + #define BOARD_LED_PIN D21 + #define BOARD_BUTTON_PIN D18 - /* External header */ + static __attribute__ ((unused)) PinMapping PIN_MAP[NR_GPIO_PINS] = { + /* Top header */ - /* D21/PC13 */ - {GPIOC_BASE, 13, ADC_INVALID, TIMER_INVALID}, - /* D22/PC14 */ - {GPIOC_BASE, 14, ADC_INVALID, TIMER_INVALID}, - /* D23/PC15 */ - {GPIOC_BASE, 15, ADC_INVALID, TIMER_INVALID}, - /* D24/PB9 */ - {GPIOB_BASE, 9, ADC_INVALID, TIMER4_CH4_CCR}, - /* D25/PD2 */ - {GPIOD_BASE, 2, ADC_INVALID, TIMER_INVALID}, - /* D26/PC10 */ - {GPIOC_BASE, 10, ADC_INVALID, TIMER_INVALID}, - /* D27/PB0 */ - {GPIOB_BASE, 0, ADC8, TIMER3_CH3_CCR}, - /* D28/PB1 */ - {GPIOB_BASE, 1, ADC9, TIMER3_CH4_CCR}, - /* D29/PB10 */ - {GPIOB_BASE, 10, ADC_INVALID, TIMER_INVALID}, - /* D30/PB11 */ - {GPIOB_BASE, 11, ADC_INVALID, TIMER_INVALID}, - /* D31/PB12 */ - {GPIOB_BASE, 12, ADC_INVALID, TIMER_INVALID}, - /* D32/PB13 */ - {GPIOB_BASE, 13, ADC_INVALID, TIMER_INVALID}, - /* D33/PB14 */ - {GPIOB_BASE, 14, ADC_INVALID, TIMER_INVALID}, - /* D34/PB15 */ - {GPIOB_BASE, 15, ADC_INVALID, TIMER_INVALID}, - /* D35/PC6 */ - {GPIOC_BASE, 6, ADC_INVALID, TIMER_INVALID}, - /* D36/PC7 */ - {GPIOC_BASE, 7, ADC_INVALID, TIMER_INVALID}, - /* D37/PC8 */ - {GPIOC_BASE, 8, ADC_INVALID, TIMER_INVALID}, - /* PC9 (BUT) */ - {GPIOC_BASE, 9, ADC_INVALID, TIMER_INVALID} + /* D0/PB10 */ + {GPIOB_BASE, 10, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, + /* D1/PB2 */ + {GPIOB_BASE, 2, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, + /* D2/PB12 */ + {GPIOB_BASE, 12, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, + /* D3/PB13 */ + {GPIOB_BASE, 13, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, + /* D4/PB14 */ + {GPIOB_BASE, 14, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, + /* D5/PB15 */ + {GPIOB_BASE, 15, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, + /* D6/PC0 */ + {GPIOC_BASE, 0, ADC10, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, + /* D7/PC1 */ + {GPIOC_BASE, 1, ADC11, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, + /* D8/PC2 */ + {GPIOC_BASE, 2, ADC12, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, + /* D9/PC3 */ + {GPIOC_BASE, 3, ADC13, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, + /* D10/PC4 */ + {GPIOC_BASE, 4, ADC14, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, + /* D11/PC5 */ + {GPIOC_BASE, 5, ADC15, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, + /* D12/PC6 */ + {GPIOC_BASE, 6, ADC_INVALID, TIMER8_CH1_CCR, EXTI_CONFIG_PORTC, TIMER8, 1}, + /* D13/PC7 */ + {GPIOC_BASE, 7, ADC_INVALID, TIMER8_CH2_CCR, EXTI_CONFIG_PORTC, TIMER8, 2}, + /* D14/PC8 */ + {GPIOC_BASE, 8, ADC_INVALID, TIMER8_CH3_CCR, EXTI_CONFIG_PORTC, TIMER8, 3}, + /* D15/PC9 */ + {GPIOC_BASE, 9, ADC_INVALID, TIMER8_CH4_CCR, EXTI_CONFIG_PORTC, TIMER8, 4}, + /* D16/PC10 */ + {GPIOC_BASE, 10, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, + /* D17/PC11 */ + {GPIOC_BASE, 11, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, + /* D18/PC12 */ + {GPIOC_BASE, 12, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, + /* D19/PC13 */ + {GPIOC_BASE, 13, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, + /* D20/PC14 */ + {GPIOC_BASE, 14, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, + /* D21/PC15 */ + {GPIOC_BASE, 15, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, + /* D22/PA8 */ + {GPIOA_BASE, 8, ADC_INVALID, TIMER1_CH1_CCR, EXTI_CONFIG_PORTA, TIMER1, 1}, + /* D23/PA9 */ + {GPIOA_BASE, 9, ADC_INVALID, TIMER1_CH2_CCR, EXTI_CONFIG_PORTA, TIMER1, 2}, + /* D24/PA10 */ + {GPIOA_BASE, 10, ADC_INVALID, TIMER1_CH3_CCR, EXTI_CONFIG_PORTA, TIMER1, 3}, + /* D25/PB9 */ + {GPIOB_BASE, 9, ADC_INVALID, TIMER4_CH4_CCR, EXTI_CONFIG_PORTB, TIMER4, 4}, + + /* Bottom header */ + + /* D26/PD2 */ + {GPIOD_BASE, 2, ADC_INVALID, 0, EXTI_CONFIG_PORTD, TIMER_INVALID, TIMER_INVALID}, + /* D27/PD3 */ + {GPIOD_BASE, 3, ADC_INVALID, 0, EXTI_CONFIG_PORTD, TIMER_INVALID, TIMER_INVALID}, + /* D28/PD6 */ + {GPIOD_BASE, 6, ADC_INVALID, 0, EXTI_CONFIG_PORTD, TIMER_INVALID, TIMER_INVALID}, + /* D29/PG11 */ + {GPIOG_BASE, 11, ADC_INVALID, 0, EXTI_CONFIG_PORTG, TIMER_INVALID, TIMER_INVALID}, + /* D30/PG12 */ + {GPIOG_BASE, 12, ADC_INVALID, 0, EXTI_CONFIG_PORTG, TIMER_INVALID, TIMER_INVALID}, + /* D31/PG13 */ + {GPIOG_BASE, 13, ADC_INVALID, 0, EXTI_CONFIG_PORTG, TIMER_INVALID, TIMER_INVALID}, + /* D32/PG14 */ + {GPIOG_BASE, 14, ADC_INVALID, 0, EXTI_CONFIG_PORTG, TIMER_INVALID, TIMER_INVALID}, + /* D33/PG8 */ + {GPIOG_BASE, 8, ADC_INVALID, 0, EXTI_CONFIG_PORTG, TIMER_INVALID, TIMER_INVALID}, + /* D34/PG7 */ + {GPIOG_BASE, 7, ADC_INVALID, 0, EXTI_CONFIG_PORTG, TIMER_INVALID, TIMER_INVALID}, + /* D35/PG6 */ + {GPIOG_BASE, 6, ADC_INVALID, 0, EXTI_CONFIG_PORTG, TIMER_INVALID, TIMER_INVALID}, + /* D36/PB5 */ + {GPIOB_BASE, 5, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, + /* D37/PB6 */ + {GPIOB_BASE, 6, ADC_INVALID, TIMER4_CH1_CCR, EXTI_CONFIG_PORTB, TIMER4, 1}, + /* D38/PB7 */ + {GPIOB_BASE, 7, ADC_INVALID, TIMER4_CH2_CCR, EXTI_CONFIG_PORTB, TIMER4, 2}, + /* D39/PF6 */ + {GPIOF_BASE, 6, ADC4, 0, EXTI_CONFIG_PORTF, TIMER_INVALID, TIMER_INVALID}, + /* D40/PF7 */ + {GPIOF_BASE, 7, ADC5, 0, EXTI_CONFIG_PORTF, TIMER_INVALID, TIMER_INVALID}, + /* D41/PF8 */ + {GPIOF_BASE, 8, ADC6, 0, EXTI_CONFIG_PORTF, TIMER_INVALID, TIMER_INVALID}, + /* D42/PF9 */ + {GPIOF_BASE, 9, ADC7, 0, EXTI_CONFIG_PORTF, TIMER_INVALID, TIMER_INVALID}, + /* D43/PF10 */ + {GPIOF_BASE, 10, ADC8, 0, EXTI_CONFIG_PORTF, TIMER_INVALID, TIMER_INVALID}, + /* D44/PF11 */ + {GPIOF_BASE, 11, ADC_INVALID, 0, EXTI_CONFIG_PORTF, TIMER_INVALID, TIMER_INVALID}, + /* D45/PB1 */ + {GPIOB_BASE, 1, ADC9, TIMER3_CH4_CCR, EXTI_CONFIG_PORTB, TIMER3, 4}, + /* D46/PB0 */ + {GPIOB_BASE, 0, ADC8, TIMER3_CH3_CCR, EXTI_CONFIG_PORTB, TIMER3, 3}, + /* D47/PA0 */ + {GPIOA_BASE, 0, ADC0, TIMER5_CH1_CCR, EXTI_CONFIG_PORTA, TIMER5, 1}, + /* D48/PA1 */ + {GPIOA_BASE, 1, ADC1, TIMER5_CH2_CCR, EXTI_CONFIG_PORTA, TIMER5, 2}, /* FIXME (?) what to do about D48--D50 + also being TIMER2_CH[2,3,4]? */ + /* D49/PA2 */ + {GPIOA_BASE, 2, ADC2, TIMER5_CH3_CCR, EXTI_CONFIG_PORTA, TIMER5, 3}, + /* D50/PA3 */ + {GPIOA_BASE, 3, ADC3, TIMER5_CH4_CCR, EXTI_CONFIG_PORTA, TIMER5, 4}, + /* D51/PA4 */ + {GPIOA_BASE, 4, ADC4, 0, EXTI_CONFIG_PORTA, TIMER_INVALID, TIMER_INVALID}, + /* D52/PA5 */ + {GPIOA_BASE, 5, ADC5, 0, EXTI_CONFIG_PORTA, TIMER_INVALID, TIMER_INVALID}, + /* D53/PA6 */ + {GPIOA_BASE, 6, ADC6, TIMER3_CH1_CCR, EXTI_CONFIG_PORTA, TIMER3, 1}, + /* D54/PA7 */ + {GPIOA_BASE, 7, ADC7, TIMER3_CH2_CCR, EXTI_CONFIG_PORTA, TIMER3, 2}, + + /* Right (triple) header */ + + /* D55/PF0 */ + {GPIOF_BASE, 0, ADC_INVALID, 0, EXTI_CONFIG_PORTF, TIMER_INVALID, TIMER_INVALID}, + /* D56/PD11 */ + {GPIOD_BASE, 11, ADC_INVALID, 0, EXTI_CONFIG_PORTD, TIMER_INVALID, TIMER_INVALID}, + /* D57/PD14 */ + {GPIOD_BASE, 14, ADC_INVALID, 0, EXTI_CONFIG_PORTD, TIMER_INVALID, TIMER_INVALID}, + /* D58/PF1 */ + {GPIOF_BASE, 1, ADC_INVALID, 0, EXTI_CONFIG_PORTF, TIMER_INVALID, TIMER_INVALID}, + /* D59/PD12 */ + {GPIOD_BASE, 12, ADC_INVALID, 0, EXTI_CONFIG_PORTD, TIMER_INVALID, TIMER_INVALID}, + /* D60/PD15 */ + {GPIOD_BASE, 15, ADC_INVALID, 0, EXTI_CONFIG_PORTD, TIMER_INVALID, TIMER_INVALID}, + /* D61/PF2 */ + {GPIOF_BASE, 2, ADC_INVALID, 0, EXTI_CONFIG_PORTF, TIMER_INVALID, TIMER_INVALID}, + /* D62/PD13 */ + {GPIOD_BASE, 13, ADC_INVALID, 0, EXTI_CONFIG_PORTD, TIMER_INVALID, TIMER_INVALID}, + /* D63/PD0 */ + {GPIOD_BASE, 0, ADC_INVALID, 0, EXTI_CONFIG_PORTD, TIMER_INVALID, TIMER_INVALID}, + /* D64/PF3 */ + {GPIOF_BASE, 3, ADC_INVALID, 0, EXTI_CONFIG_PORTF, TIMER_INVALID, TIMER_INVALID}, + /* D65/PE3 */ + {GPIOE_BASE, 3, ADC_INVALID, 0, EXTI_CONFIG_PORTE, TIMER_INVALID, TIMER_INVALID}, + /* D66/PD1 */ + {GPIOD_BASE, 1, ADC_INVALID, 0, EXTI_CONFIG_PORTD, TIMER_INVALID, TIMER_INVALID}, + /* D67/PF4 */ + {GPIOF_BASE, 4, ADC_INVALID, 0, EXTI_CONFIG_PORTF, TIMER_INVALID, TIMER_INVALID}, + /* D68/PE4 */ + {GPIOE_BASE, 4, ADC_INVALID, 0, EXTI_CONFIG_PORTE, TIMER_INVALID, TIMER_INVALID}, + /* D69/PE7 */ + {GPIOE_BASE, 7, ADC_INVALID, 0, EXTI_CONFIG_PORTE, TIMER_INVALID, TIMER_INVALID}, + /* D70/PF5 */ + {GPIOF_BASE, 5, ADC_INVALID, 0, EXTI_CONFIG_PORTF, TIMER_INVALID, TIMER_INVALID}, + /* D71/PE5 */ + {GPIOE_BASE, 5, ADC_INVALID, 0, EXTI_CONFIG_PORTE, TIMER_INVALID, TIMER_INVALID}, + /* D72/PE8 */ + {GPIOE_BASE, 8, ADC_INVALID, 0, EXTI_CONFIG_PORTE, TIMER_INVALID, TIMER_INVALID}, + /* D73/PF12 */ + {GPIOF_BASE, 12, ADC_INVALID, 0, EXTI_CONFIG_PORTF, TIMER_INVALID, TIMER_INVALID}, + /* D74/PE6 */ + {GPIOE_BASE, 6, ADC_INVALID, 0, EXTI_CONFIG_PORTE, TIMER_INVALID, TIMER_INVALID}, + /* D75/PE9 */ + {GPIOE_BASE, 9, ADC_INVALID, 0, EXTI_CONFIG_PORTE, TIMER_INVALID, TIMER_INVALID}, + /* D76/PF13 */ + {GPIOF_BASE, 13, ADC_INVALID, 0, EXTI_CONFIG_PORTF, TIMER_INVALID, TIMER_INVALID}, + /* D77/PE10 */ + {GPIOE_BASE, 10, ADC_INVALID, 0, EXTI_CONFIG_PORTE, TIMER_INVALID, TIMER_INVALID}, + /* D78/PF14 */ + {GPIOF_BASE, 14, ADC_INVALID, 0, EXTI_CONFIG_PORTF, TIMER_INVALID, TIMER_INVALID}, + /* D79/PG9 */ + {GPIOG_BASE, 9, ADC_INVALID, 0, EXTI_CONFIG_PORTG, TIMER_INVALID, TIMER_INVALID}, + /* D80/PE11 */ + {GPIOE_BASE, 11, ADC_INVALID, 0, EXTI_CONFIG_PORTE, TIMER_INVALID, TIMER_INVALID}, + /* D81/PF15 */ + {GPIOF_BASE, 15, ADC_INVALID, 0, EXTI_CONFIG_PORTF, TIMER_INVALID, TIMER_INVALID}, + /* D82/PG10 */ + {GPIOG_BASE, 10, ADC_INVALID, 0, EXTI_CONFIG_PORTG, TIMER_INVALID, TIMER_INVALID}, + /* D83/PE12 */ + {GPIOE_BASE, 12, ADC_INVALID, 0, EXTI_CONFIG_PORTE, TIMER_INVALID, TIMER_INVALID}, + /* D84/PG0 */ + {GPIOG_BASE, 0, ADC_INVALID, 0, EXTI_CONFIG_PORTG, TIMER_INVALID, TIMER_INVALID}, + /* D85/PD5 */ + {GPIOD_BASE, 5, ADC_INVALID, 0, EXTI_CONFIG_PORTD, TIMER_INVALID, TIMER_INVALID}, + /* D86/PE13 */ + {GPIOE_BASE, 13, ADC_INVALID, 0, EXTI_CONFIG_PORTE, TIMER_INVALID, TIMER_INVALID}, + /* D87/PG1 */ + {GPIOG_BASE, 1, ADC_INVALID, 0, EXTI_CONFIG_PORTG, TIMER_INVALID, TIMER_INVALID}, + /* D88/PD4 */ + {GPIOD_BASE, 4, ADC_INVALID, 0, EXTI_CONFIG_PORTD, TIMER_INVALID, TIMER_INVALID}, + /* D89/PE14 */ + {GPIOE_BASE, 14, ADC_INVALID, 0, EXTI_CONFIG_PORTE, TIMER_INVALID, TIMER_INVALID}, + /* D90/PG2 */ + {GPIOG_BASE, 2, ADC_INVALID, 0, EXTI_CONFIG_PORTG, TIMER_INVALID, TIMER_INVALID}, + /* D91/PE1 */ + {GPIOE_BASE, 1, ADC_INVALID, 0, EXTI_CONFIG_PORTE, TIMER_INVALID, TIMER_INVALID}, + /* D92/PE15 */ + {GPIOE_BASE, 15, ADC_INVALID, 0, EXTI_CONFIG_PORTE, TIMER_INVALID, TIMER_INVALID}, + /* D93/PG3 */ + {GPIOG_BASE, 3, ADC_INVALID, 0, EXTI_CONFIG_PORTG, TIMER_INVALID, TIMER_INVALID}, + /* D94/PE0 */ + {GPIOE_BASE, 0, ADC_INVALID, 0, EXTI_CONFIG_PORTE, TIMER_INVALID, TIMER_INVALID}, + /* D95/PD8 */ + {GPIOD_BASE, 8, ADC_INVALID, 0, EXTI_CONFIG_PORTD, TIMER_INVALID, TIMER_INVALID}, + /* D96/PG4 */ + {GPIOG_BASE, 4, ADC_INVALID, 0, EXTI_CONFIG_PORTG, TIMER_INVALID, TIMER_INVALID}, + /* D97/PD9 */ + {GPIOD_BASE, 9, ADC_INVALID, 0, EXTI_CONFIG_PORTD, TIMER_INVALID, TIMER_INVALID}, + /* D98/PG5 */ + {GPIOG_BASE, 5, ADC_INVALID, 0, EXTI_CONFIG_PORTG, TIMER_INVALID, TIMER_INVALID}, + /* D99/PD10 */ + {GPIOD_BASE, 10, ADC_INVALID, 0, EXTI_CONFIG_PORTD, TIMER_INVALID, TIMER_INVALID} }; - static __attribute__((unused)) ExtiInfo PIN_TO_EXTI_CHANNEL[NR_GPIO_PINS] = - { - /* D0/PA3 */ - {EXTI3, EXTI_CONFIG_PORTA}, - /* D1/PA2 */ - {EXTI2, EXTI_CONFIG_PORTA}, - /* D2/PA0 */ - {EXTI0, EXTI_CONFIG_PORTA}, - /* D3/PA1 */ - {EXTI1, EXTI_CONFIG_PORTA}, - /* D4/PB5 */ - {EXTI5, EXTI_CONFIG_PORTB}, - /* D5/PB6 */ - {EXTI6, EXTI_CONFIG_PORTB}, - /* D6/PA8 */ - {EXTI8, EXTI_CONFIG_PORTA}, - /* D7/PA9 */ - {EXTI9, EXTI_CONFIG_PORTA}, - /* D8/PA10 */ - {EXTI10, EXTI_CONFIG_PORTA}, - /* D9/PB7 */ - {EXTI7, EXTI_CONFIG_PORTB}, - /* D10/PA4 */ - {EXTI4, EXTI_CONFIG_PORTA}, - /* D11/PA7 */ - {EXTI7, EXTI_CONFIG_PORTA}, - /* D12/PA6 */ - {EXTI6, EXTI_CONFIG_PORTA}, - /* D13/PA5 */ - {EXTI5, EXTI_CONFIG_PORTA}, - }; + #define BOARD_INIT do { \ + } while(0) #elif defined(BOARD_maple_mini) @@ -304,74 +402,74 @@ typedef struct PinMapping { #define BOARD_LED_PIN 33 static __attribute__ ((unused)) PinMapping PIN_MAP[NR_GPIO_PINS] = { - /* D0/PC15 */ - {GPIOC_BASE, 15, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, - /* D1/PA0 */ - {GPIOA_BASE, 0, ADC0, TIMER2_CH1_CCR, EXTI_CONFIG_PORTA, TIMER2, 1}, - /* D2/PA1 */ - {GPIOA_BASE, 1, ADC1, TIMER2_CH2_CCR, EXTI_CONFIG_PORTA, TIMER2, 2}, - /* D3/PA2 */ - {GPIOA_BASE, 2, ADC2, TIMER2_CH3_CCR, EXTI_CONFIG_PORTA, TIMER2, 3}, - /* D4/PA3 */ - {GPIOA_BASE, 3, ADC3, TIMER2_CH4_CCR, EXTI_CONFIG_PORTA, TIMER2, 4}, - /* D5/PA4 */ - {GPIOA_BASE, 4, ADC4, 0, EXTI_CONFIG_PORTA, TIMER_INVALID, TIMER_INVALID}, + /* D0/PB11 */ + {GPIOB_BASE, 11, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, + /* D1/PB10 */ + {GPIOB_BASE, 10, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, + /* D2/PB2 */ + {GPIOB_BASE, 2, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, + /* D3/PB0 */ + {GPIOB_BASE, 0, ADC8, TIMER3_CH3_CCR, EXTI_CONFIG_PORTB, TIMER3, 3}, + /* D4/PA7 */ + {GPIOA_BASE, 7, ADC7, TIMER3_CH2_CCR, EXTI_CONFIG_PORTA, TIMER3, 2}, + /* D5/PA6 */ + {GPIOA_BASE, 6, ADC6, TIMER3_CH1_CCR, EXTI_CONFIG_PORTA, TIMER3, 1}, /* D6/PA5 */ {GPIOA_BASE, 5, ADC5, 0, EXTI_CONFIG_PORTA, TIMER_INVALID, TIMER_INVALID}, - /* D7/PA6 */ - {GPIOA_BASE, 6, ADC6, TIMER3_CH1_CCR, EXTI_CONFIG_PORTA, TIMER3, 1}, - /* D8/PA7 */ - {GPIOA_BASE, 7, ADC7, TIMER3_CH2_CCR, EXTI_CONFIG_PORTA, TIMER3, 2}, - /* D9/PB0 */ - {GPIOB_BASE, 0, ADC8, TIMER3_CH3_CCR, EXTI_CONFIG_PORTB, TIMER3, 3}, - /* D10/PB1 */ - {GPIOB_BASE, 1, ADC9, TIMER3_CH4_CCR, EXTI_CONFIG_PORTB, TIMER3, 4}, - /* D11/PB2 */ - {GPIOB_BASE, 2, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, - /* D12/PB10 */ - {GPIOB_BASE, 10, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, - /* D13/PB11 */ - {GPIOB_BASE, 11, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, - /* D14/PB13 */ - {GPIOB_BASE, 13, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, - /* D15/PB14 */ - {GPIOB_BASE, 14, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, - /* D16/PB15 */ - {GPIOB_BASE, 15, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, - /* D17/PA8 */ - {GPIOA_BASE, 8, ADC_INVALID, TIMER1_CH1_CCR, EXTI_CONFIG_PORTB, TIMER1, 1}, - /* D18/PA9 */ - {GPIOA_BASE, 9, ADC_INVALID, TIMER1_CH2_CCR, EXTI_CONFIG_PORTA, TIMER2, 2}, - /* D19/PA10 */ - {GPIOA_BASE, 10, ADC_INVALID, TIMER1_CH3_CCR, EXTI_CONFIG_PORTA, TIMER1, 3}, - /* D20/PA11 */ - {GPIOA_BASE, 11, ADC_INVALID, TIMER1_CH4_CCR, EXTI_CONFIG_PORTA, TIMER1, 4}, - /* D21/PA12 */ - {GPIOA_BASE, 12, ADC_INVALID, 0, EXTI_CONFIG_PORTA, TIMER_INVALID, TIMER_INVALID}, + /* D7/PA4 */ + {GPIOA_BASE, 4, ADC4, 0, EXTI_CONFIG_PORTA, TIMER_INVALID, TIMER_INVALID}, + /* D8/PA3 */ + {GPIOA_BASE, 3, ADC3, TIMER2_CH4_CCR, EXTI_CONFIG_PORTA, TIMER2, 4}, + /* D9/PA2 */ + {GPIOA_BASE, 2, ADC2, TIMER2_CH3_CCR, EXTI_CONFIG_PORTA, TIMER2, 3}, + /* D10/PA1 */ + {GPIOA_BASE, 1, ADC1, TIMER2_CH2_CCR, EXTI_CONFIG_PORTA, TIMER2, 2}, + /* D11/PA0 */ + {GPIOA_BASE, 0, ADC0, TIMER2_CH1_CCR, EXTI_CONFIG_PORTA, TIMER2, 1}, + /* D12/PC15 */ + {GPIOC_BASE, 15, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, + /* D13/PC14 */ + {GPIOC_BASE, 14, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, + /* D14/PC13 */ + {GPIOC_BASE, 13, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, + /* D15/PB7 */ + {GPIOB_BASE, 7, ADC_INVALID, TIMER4_CH2_CCR, EXTI_CONFIG_PORTB, TIMER4, 1}, + /* D16/PB6 */ + {GPIOB_BASE, 6, ADC_INVALID, TIMER4_CH1_CCR, EXTI_CONFIG_PORTB, TIMER4, 1}, + /* D17/PB5 */ + {GPIOB_BASE, 5, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, + /* D18/PB4 */ + {GPIOB_BASE, 4, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, + /* D19/PB3 */ + {GPIOB_BASE, 3, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, + /* D20/PA15 */ + {GPIOA_BASE, 15, ADC_INVALID, 0, EXTI_CONFIG_PORTA, TIMER_INVALID, TIMER_INVALID}, + /* D21/PA14 */ + {GPIOA_BASE, 14, ADC_INVALID, 0, EXTI_CONFIG_PORTA, TIMER_INVALID, TIMER_INVALID}, /* D22/PA13 */ {GPIOA_BASE, 13, ADC_INVALID, 0, EXTI_CONFIG_PORTA, TIMER_INVALID, TIMER_INVALID}, - /* D23/PA14 */ - {GPIOA_BASE, 14, ADC_INVALID, 0, EXTI_CONFIG_PORTA, TIMER_INVALID, TIMER_INVALID}, - /* D24/PA15 */ - {GPIOA_BASE, 15, ADC_INVALID, 0, EXTI_CONFIG_PORTA, TIMER_INVALID, TIMER_INVALID}, - /* D25/PB3 */ - {GPIOB_BASE, 3, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, - /* D26/PB4 */ - {GPIOB_BASE, 4, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, - /* D27/PB5 */ - {GPIOB_BASE, 5, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, - /* D28/PB6 */ - {GPIOB_BASE, 6, ADC_INVALID, TIMER4_CH1_CCR, EXTI_CONFIG_PORTB, TIMER4, 1}, - /* D29/PB7 */ - {GPIOB_BASE, 7, ADC_INVALID, TIMER4_CH2_CCR, EXTI_CONFIG_PORTB, TIMER4, 1}, - /* D30/PC13 */ - {GPIOC_BASE, 13, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, - /* D31/PC14 */ - {GPIOC_BASE, 14, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, + /* D23/PA12 */ + {GPIOA_BASE, 12, ADC_INVALID, 0, EXTI_CONFIG_PORTA, TIMER_INVALID, TIMER_INVALID}, + /* D24/PA11 */ + {GPIOA_BASE, 11, ADC_INVALID, TIMER1_CH4_CCR, EXTI_CONFIG_PORTA, TIMER1, 4}, + /* D25/PA10 */ + {GPIOA_BASE, 10, ADC_INVALID, TIMER1_CH3_CCR, EXTI_CONFIG_PORTA, TIMER1, 3}, + /* D26/PA9 */ + {GPIOA_BASE, 9, ADC_INVALID, TIMER1_CH2_CCR, EXTI_CONFIG_PORTA, TIMER2, 2}, + /* D27/PA8 */ + {GPIOA_BASE, 8, ADC_INVALID, TIMER1_CH1_CCR, EXTI_CONFIG_PORTB, TIMER1, 1}, + /* D28/PB15 */ + {GPIOB_BASE, 15, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, + /* D29/PB14 */ + {GPIOB_BASE, 14, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, + /* D30/PB13 */ + {GPIOB_BASE, 13, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, + /* D31/PB12 */ + {GPIOB_BASE, 12, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, /* D32/PB8 */ {GPIOB_BASE, 8, ADC_INVALID, TIMER4_CH3_CCR, EXTI_CONFIG_PORTB, TIMER4, 3}, - /* D33/PB12 */ - {GPIOB_BASE, 12, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, + /* D33/PB1 */ + {GPIOB_BASE, 1, ADC9, TIMER3_CH4_CCR, EXTI_CONFIG_PORTB, TIMER3, 4}, }; /* since we want the Serial Wire/JTAG pins as GPIOs, disable both |