aboutsummaryrefslogtreecommitdiffstats
path: root/docs/source/usb.rst
diff options
context:
space:
mode:
Diffstat (limited to 'docs/source/usb.rst')
-rw-r--r--docs/source/usb.rst186
1 files changed, 185 insertions, 1 deletions
diff --git a/docs/source/usb.rst b/docs/source/usb.rst
index 2460df5..1ce91f0 100644
--- a/docs/source/usb.rst
+++ b/docs/source/usb.rst
@@ -1,7 +1,191 @@
+.. highlight:: cpp
+
.. _usb:
=====
USB
=====
-Stub.
+.. note:: Changes and Caveats
+
+ The SerialUSB functionality was modified for the 0.0.6 IDE
+ release. It now includes a 50 millisecond timeout for writes and
+ does not try to detect if the USB host is "really" connected or
+ just enumerated and initialized. This means that if you have a
+ number of SerialUSB writes or prints in your code and you are not
+ monitoring on a computer your program will run much, much slower
+ than if it is being monitored or totally disconnected (battery).
+
+ You can avoid this behavior by :ref:`deciphering the port status
+ <usb-safe-print>` using the DTR and RTS line status; the behavior
+ of these control lines is platform dependent and we no longer
+ interpret them by default.
+
+The Maple STM32 microprocessor includes a dedicated USB peripheral
+which can be configured to act as a general USB slave device with
+transfer rates up to 12Mbps (it unfortunately can't be configured as a
+host or on-the-go device). By default, the peripheral is configured
+for two uses: first, to receive sketch/program uploads from the IDE,
+and second, to emulate a regular serial port for use as a terminal
+(text read/write).
+
+The emulated terminal is relatively slow and inefficient; it is best
+for transferring data at regular serial speeds (kilobaud). Users
+requiring faster data transfer should consider implementing a
+different communications protocol; the Maple could be reprogrammed to
+appear as a mass storage device (thumb drive), human interface device
+(mouse or keyboard), microphone, or any other USB device.
+
+The SerialUSB channel is also used as part of the auto-reset feature
+of the IDE to program the board (on Maple Rev3): a :ref:`magic
+sequence of control line toggles and transmitted data
+<bootloader-rev3>` causes the Maple to reset itself and enter
+bootloader mode. As an unfortunate consequence, the auto-reset will
+not work if the IDE can not access the serial port, either due to a
+conflict with another program (serial monitor) or because the
+interface has been disabled from the Maple side (through
+``SerialUSB.end()``).
+
+Function Reference
+------------------
+
+``SerialUSB.print(...)``/\ ``SerialUSB.println(...)``
+
+ Writes data into the port buffer to be transmitted as soon as
+ possible. Accepts strings (``char*``). If a raw integer is passed
+ the corresponding ASCII character will be transmitted; to print
+ out a number in human readable form add a second parameter with
+ the base system. For example, to print out the decimal number
+ "1234", use ``SerialUSB.print(1234, DEC)``; to print out the
+ binary number "1001", use ``SerialUSB.print(9, BIN)``.
+
+.. _usb-write:
+
+``SerialUSB.write(bytes)``
+
+ ``write`` is a lower-level function that writes bytes directly
+ into the buffer. :ref:`print() <usb-print>` often calls this
+ function dozens of times to write out a single formatted number;
+ user code can optimize raw data speed by calling this function
+ with 64-byte chunks instead.
+
+``SerialUSB.available()``/\ ``SerialUSB.read()``
+
+ ``SerialUSB.read()`` will return the next available character
+ (``byte``) that has been received over the port.
+ ``SerialUSB.available()`` returns how many such bytes are actually
+ available. If there is no data, ``read`` will block/fail, so the
+ usual program structure is to poll with ``available`` and only
+ ``read`` if there are data to read.
+
+``SerialUSB.read(buffer, length)``
+
+ An alternative version of ``SerialUSB.read``; will write the next
+ ``length`` available characters into the array ``buffer``.
+
+``SerialUSB.pending()``
+
+ Returns the number of bytes waiting in the transmit
+ buffer. Usercode can use this to prevent any blocking/waiting when
+ using the direct :ref:`write <usb-write>` functions, or to check
+ if data was actually requested/received by the host.
+
+``SerialUSB.getRTS()``
+
+ Returns the state (1 or 0) of the virtual RTS ("ready to send")
+ line. This can be used to guess if the USB host is actively
+ waiting for data (e.g., if a serial monitor program is running) or
+ just "configured" (i.e., the virtual serial port is configured,
+ but no program is reading data).
+
+``SerialUSB.getDTR()``
+
+ Returns the state (1 or 0) of the virtual DTR ("data terminal
+ ready") line. This can be used to guess if the USB host is
+ actively waiting for data (e.g., if a serial monitor program is
+ running) or just "configured" (i.e., the virtual serial port is
+ configured, but no program is reading data).
+
+.. TODO deprecate crap out of above two functions; write a sane API
+
+``SerialUSB.isConnected()``
+
+ Returns 1 if the USB host is connected and the virtual serial
+ interface is initialized (though not necessarily active).
+ Otherwise, returns 0.
+
+``SerialUSB.end()``/\ ``SerialUSB.begin()``
+
+ The USB peripheral is enabled by default so that the auto-reset
+ feature will work, but it can be disabled/restarted at any time
+ with the ``SerialUSB.end()`` and ``SerialUSB.begin()``
+ functions.
+
+ ``SerialUSB.end()`` is a relatively hard shutdown, similar to
+ unplugging the board; this may crash or confuse any programs
+ running host-side. Note that calling this function will require
+ the Maple to be put into :ref:`perpetual bootloader mode
+ <troubleshooting-perpetual-bootloader>` before another program can
+ be uploaded onto it, unless ``SerialUSB.begin()`` is called before
+ the upload is attempted.
+
+ It's probably wise to wait a few seconds between calls to
+ ``SerialUSB.end()`` and ``SerialUSB.begin()`` (or to
+ ``SerialUSB.begin()`` and ``SerialUSB.print()``) to let the
+ computer reconfigure.
+
+Code Examples
+-------------
+
+.. _usb-safe-print:
+
+Safe Print
+^^^^^^^^^^
+
+This function should run smoothly and not block; the LED should blink
+at roughly the same speed whether being monitored, running from
+battery, or connected but not monitored. You may need to experiment
+with the DTR/RTS logic for your platform and device configuration. ::
+
+ #define LED_PIN 13
+
+ void setup() {
+ /* Set up the LED to blink */
+ pinMode(LED_PIN, OUTPUT);
+ }
+
+ void loop() {
+ // LED will stay off if we are disconnected;
+ // will blink quickly if USB is unplugged (battery etc)
+ if(SerialUSB.isConnected()) {
+ digitalWrite(LED_PIN, 1);
+ }
+ delay(100);
+
+ // If this logic fails to detect if bytes are going to
+ // be read by the USB host, then the println() will fully
+ // many times, causing a very slow LED blink.
+ // If the characters are printed and read, the blink will
+ // only slow a small amount when "really" connected, and fast
+ // when the virtual port is only configured.
+ if(SerialUSB.isConnected() && (SerialUSB.getDTR() || SerialUSB.getRTS())) {
+ for(int i=0; i<10; i++) {
+ SerialUSB.println(123456,BIN);
+ }
+ }
+ digitalWrite(LED_PIN, 0);
+ delay(100);
+ }
+
+Recommended Reading
+-------------------
+
+* `USB in a NutShell <http://www.beyondlogic.org/usbnutshell/usb1.htm>`_ overview from Beyond Logic
+* `Wikipedia article on Universal Serial Bus (USB) <http://en.wikipedia.org/wiki/Universal_Serial_Bus>`_
+* Linux Kernel documentation for `USB ACM <http://www.kernel.org/doc/Documentation/usb/acm.txt>`_ and `USB Serial <http://www.kernel.org/doc/Documentation/usb/usb-serial.txt>`_
+* STMicro documentation for STM32F103RB microcontroller:
+
+ * `All documents <http://www.st.com/mcu/devicedocs-STM32F103RB-110.html>`_
+ * `Datasheet <http://www.st.com/stonline/products/literature/ds/13587.pdf>`_ (pdf)
+ * `Reference Manual <http://www.st.com/stonline/products/literature/rm/13902.pdf>`_ (pdf)
+ * `Programming Manual <http://www.st.com/stonline/products/literature/pm/15491.pdf>`_ (pdf; assembly language and register reference)