From 9579e9487c2039df38cc4fd0ac2846ef07cc0947 Mon Sep 17 00:00:00 2001 From: Marti Bolivar Date: Fri, 11 Mar 2011 20:43:59 -0500 Subject: shiftOut(), docs fixes --- docs/source/bootloader.rst | 56 ++++++------ docs/source/lang/api/constants.rst | 8 -- docs/source/lang/api/shiftout.rst | 99 ++++++++++++++++++++ docs/source/lang/unimplemented/shiftout.rst | 136 ---------------------------- docs/source/language-index.rst | 1 - docs/source/language.rst | 9 +- wirish/io.h | 16 ++++ 7 files changed, 148 insertions(+), 177 deletions(-) create mode 100644 docs/source/lang/api/shiftout.rst delete mode 100644 docs/source/lang/unimplemented/shiftout.rst diff --git a/docs/source/bootloader.rst b/docs/source/bootloader.rst index 57833ed..cfbf545 100644 --- a/docs/source/bootloader.rst +++ b/docs/source/bootloader.rst @@ -66,7 +66,7 @@ have embedded USB support. Thus, Maple doesn’t need the extra FTDI chip. Firmware is uploaded via the standard DFU protocol (also used by iPhone and openMoko). Since DFU is a standard, there is no need for custom software running on the host to upload the firmware. Any DFU -compliant program will work. The maple ide is based around +compliant program will work. The Maple IDE is based around :command:`dfu-util`, openMoko’s DFU utility. Using DFU came at a cost, however. The USB port must additionally implement a separate serial port at the same time (we use the CDC ACM class for serial @@ -87,11 +87,11 @@ important what this means, except for two things. 1. Four drivers were necessary to make everything work. 2. IAD is not supported by OS X. -Mac, on the other hand, only supported Compound USB, a different trick -that is not supported by Windows. While a perpetual background +Mac OS X, on the other hand, only supported Compound USB, a different +trick that is not supported by Windows. While a perpetual background bootloader was attractive, it became clear, after much toiling, we -were going to have to write some custom drivers across several -platforms to make everything work this way. +were going to have to write custom drivers across several platforms to +make everything work this way. .. _bootloader-rev3: @@ -103,22 +103,21 @@ Arduino. In Rev 3, the device resets into bootloader mode, which stays alive for a few moments to receive commands, and then jumps to user code. The bootloader is implemented as a DFU device -- just a DFU device, no serial port. This requires one driver for Windows -(:file:`drivers/mapleDrv/dfu` in the Windows IDE directory). As part -of the :ref:`libmaple ` library, user code is automatically -supplied with serial support via some behind the scenes work that -happens automatically when you compile (``setupUSB()`` is appended to -``setup()``). This user mode code only implements a CDC ACM class USB -device, giving you functions like ``Usb.print()``. Separating these -two modes fixed the driver issue, required no complicated compound USB -device nonsense, and works well across platforms, requiring only two -drivers (serial and DFU) on Windows. +(:file:`drivers/mapleDrv/dfu` in the Windows IDE directory). + +As part of the :ref:`libmaple ` library, user code is +automatically supplied with serial support via some behind the scenes +work (``setupUSB()`` is called from ``init()``). This user mode code +only implements a CDC ACM class USB device, giving you functions like +:ref:`SerialUSB.read() `. Separating these two +modes fixed the driver issues and works well across platforms, +requiring only two drivers (serial and DFU) on Windows. However, it is no longer possible to upload code at will, since there -is no bootloader quietly listening in the background. Instead you have -to reset the board, then initiate a DFU transaction. This reset is -performed automatically by the IDE by sending a command over the USB -serial port. You can generate this reset on your own using a Python -script or some other scheme. All you need do is: +is no bootloader quietly listening in the background. Instead, you +must reset the board, then initiate a DFU transaction. The IDE +performs this reset automatically by performing a special sequence of +changes on the USB serial port: 1. Pulse DTR (high and then low, so that you've created a negative edge) @@ -128,15 +127,16 @@ script or some other scheme. All you need do is: negative edge, rather than just ensuring DTR is low. After the reset, the host OS takes a few moments (.5-2 seconds) to -re-enumerate the device as DFU. This delay is unpredictable, and its -the reason the bootloader on Maple Rev3 stays alive for so -long. Sometimes the bootloader was exiting before the OS had even -enumerated the device! Once in bootloader mode, however, -:command:`dfu-util` uploads your sketch into either flash or RAM (DFU -alternate setting 0 or 1, respectively) and resets the board again. -This time, however, no DFU transaction is initiated, and the -bootloader gives way to user code, closing down the DFU pipe and -bringing up the USB serial. +re-enumerate the device as DFU. This delay is unpredictable, and is +the reason the bootloader on Maple Rev 3/Rev 5 stays alive for so +long. (Sometimes, the bootloader was exiting before the OS had even +enumerated the device.) + +Once in bootloader mode, :command:`dfu-util` uploads your sketch into +either flash or RAM (DFU alternate setting 0 or 1, respectively) and +resets the board again. This time, however, no DFU transaction is +initiated, and the bootloader gives way to user code, closing down the +DFU pipe and bringing up the USB serial port. .. .. _bootloader-rev6: diff --git a/docs/source/lang/api/constants.rst b/docs/source/lang/api/constants.rst index 72738b8..2e968e7 100644 --- a/docs/source/lang/api/constants.rst +++ b/docs/source/lang/api/constants.rst @@ -61,14 +61,6 @@ pin is configured as an ``INPUT`` (using :ref:`pinMode() `, the microcontroller will report ``HIGH`` if a voltage of 3 volts or more is present at the pin. -.. TODO? Following seems false; check it out sometime, leave out for now: - -.. A pin may also be configured as an ``INPUT`` with ``pinMode()``, and -.. subsequently made ``HIGH`` with :ref:`digitalWrite() -.. `, this will set the internal pullup resistors, -.. which will *steer* the input pin to a HIGH reading unless it is pulled -.. LOW by external circuitry. - When a pin is configured to ``OUTPUT`` with pinMode, and set to ``HIGH`` with :ref:`digitalWrite() `, the pin is at 3.3 volts. In this state it can *source* current, e.g. light an LED diff --git a/docs/source/lang/api/shiftout.rst b/docs/source/lang/api/shiftout.rst new file mode 100644 index 0000000..1d9ba12 --- /dev/null +++ b/docs/source/lang/api/shiftout.rst @@ -0,0 +1,99 @@ +.. highlight:: cpp + +.. _lang-shiftout: + +shiftOut() +========== + +Shift out a byte of data, one bit at a time. + +.. contents:: Contents + :local: + +Library Documentation +--------------------- + +.. doxygenfunction:: shiftOut + +Discussion +---------- + +This is a software implementation. There is also a hardware :ref:`SPI +` library available which will be faster and consume less CPU +cycles than this function. + +Note that the ``dataPin`` and ``clockPin`` must already be configured +to :ref:`OUTPUT ` mode by a call to +:ref:`pinMode() `. + +Also note that since shiftOut() outputs 1 byte (8 bits) at a time, it +requires multiple steps to output values larger than 255. + +Examples +-------- + +To use these examples, replace ``dataPin`` and ``clockPin`` with the +numbers of the pins you want to use:: + + /* MSBFIRST example */ + + uint16 data = 500; + // shift out high byte + shiftOut(dataPin, clockPin, MSBFIRST, (data >> 8)); + // shift out low byte + shiftOut(dataPin, clockPin, MSBFIRST, data); + + /* LSBFIRST serial */ + + data = 500; + // shift out low byte + shiftOut(dataPin, clockPin, LSBFIRST, data); + // shift out high byte + shiftOut(dataPin, clockPin, LSBFIRST, (data >> 8)); + +Arduino Tutorial Example +------------------------ + +This Arduino example runs unmodified on the Maple. For accompanying +circuit, see the `tutorial on controlling a 74HC595 shift register +`_. + +:: + + //**************************************************************// + // Name : shiftOutCode, Hello World // + // Author : Carlyn Maw, Tom Igoe // + // Date : 25 Oct, 2006 // + // Version : 1.0 // + // Notes : Code for using a 74HC595 Shift Register // + // : to count from 0 to 255 // + //**************************************************************// + + // Pin connected to ST_CP of 74HC595 + int latchPin = 8; + // Pin connected to SH_CP of 74HC595 + int clockPin = 12; + // Pin connected to DS of 74HC595 + int dataPin = 11; + + void setup() { + // Set pins to output because they are addressed in the main loop + pinMode(latchPin, OUTPUT); + pinMode(clockPin, OUTPUT); + pinMode(dataPin, OUTPUT); + } + + void loop() { + // Count up routine + for (int j = 0; j < 256; j++) { + // Ground latchPin and hold low for as long as you are transmitting + digitalWrite(latchPin, LOW); + shiftOut(dataPin, clockPin, LSBFIRST, j); + // Return the latch pin high to signal chip that it + // no longer needs to listen for information + digitalWrite(latchPin, HIGH); + delay(1000); + } + } + +.. include:: /lang/cc-attribution.txt diff --git a/docs/source/lang/unimplemented/shiftout.rst b/docs/source/lang/unimplemented/shiftout.rst deleted file mode 100644 index ff3852f..0000000 --- a/docs/source/lang/unimplemented/shiftout.rst +++ /dev/null @@ -1,136 +0,0 @@ -.. _lang-shiftout: - -shiftOut() -========== - -Description ------------ - -Shifts out a byte of data one bit at a time. Starts from either the -most (i.e. the leftmost) or least (rightmost) significant bit. Each -bit is written in turn to a data pin, after which a clock pin is -pulsed to indicate that the bit is available. - - - -This is a software implementation; Arduino (as of 0019) also -provides an `SPI library `_ -that uses the hardware implementation. - - - -Syntax ------- - -shiftOut(dataPin, clockPin, bitOrder, value) - - - -Parameters ----------- - -dataPin: the pin on which to output each bit (*int*) - - - -clockPin: the pin to toggle once the **dataPin** has been set to -the correct value (*int*) - - - -bitOrder: which order to shift out the bits; either **MSBFIRST** or -**LSBFIRST**. -(Most Significant Bit First, or, Least Significant Bit First) - - - -value: the data to shift out. (*byte*) - - - -Returns -------- - -None - - - -Note ----- - -The **dataPin** and **clockPin** must already be configured as -outputs by a call to -`pinMode `_\ (). - - - -**shiftOut** is currently written to output 1 byte (8 bits) so it -requires a two step operation to output values larger than 255. - -:: - - // Do this for MSBFIRST serial - int data = 500; - // shift out highbyte - shiftOut(dataPin, clock, MSBFIRST, (data >> 8)); - // shift out lowbyte - shiftOut(data, clock, MSBFIRST, data); - - // Or do this for LSBFIRST serial - data = 500; - // shift out lowbyte - shiftOut(dataPin, clock, LSBFIRST, data); - // shift out highbyte - shiftOut(dataPin, clock, LSBFIRST, (data >> 8)); - - - -Example -------- - -*For accompanying circuit, see the `tutorial on controlling a 74HC595 shift register `_.* - - - -:: - - //**************************************************************// - // Name : shiftOutCode, Hello World // - // Author : Carlyn Maw,Tom Igoe // - // Date : 25 Oct, 2006 // - // Version : 1.0 // - // Notes : Code for using a 74HC595 Shift Register // - // : to count from 0 to 255 // - //**************************************************************** - - //Pin connected to ST_CP of 74HC595 - int latchPin = 8; - //Pin connected to SH_CP of 74HC595 - int clockPin = 12; - ////Pin connected to DS of 74HC595 - int dataPin = 11; - - void setup() { - //set pins to output because they are addressed in the main loop - pinMode(latchPin, OUTPUT); - pinMode(clockPin, OUTPUT); - pinMode(dataPin, OUTPUT); - } - - void loop() { - //count up routine - for (int j = 0; j < 256; j++) { - //ground latchPin and hold low for as long as you are transmitting - digitalWrite(latchPin, LOW); - shiftOut(dataPin, clockPin, LSBFIRST, j); - //return the latch pin high to signal chip that it - //no longer needs to listen for information - digitalWrite(latchPin, HIGH); - delay(1000); - } - } - - - - -.. include:: /lang/cc-attribution.txt diff --git a/docs/source/language-index.rst b/docs/source/language-index.rst index 3c55c33..c949988 100644 --- a/docs/source/language-index.rst +++ b/docs/source/language-index.rst @@ -33,7 +33,6 @@ programmers familiar with the Arduino language. lang/unimplemented/notone.rst lang/unimplemented/pulsein.rst - lang/unimplemented/shiftout.rst lang/unimplemented/stringclass.rst lang/unimplemented/stringobject.rst lang/unimplemented/tone.rst diff --git a/docs/source/language.rst b/docs/source/language.rst index b2f4650..d340aec 100644 --- a/docs/source/language.rst +++ b/docs/source/language.rst @@ -61,7 +61,7 @@ A more exhaustive index is available at the :ref:`language-index`. | |* :ref:`boolean ` (1 byte) | | |* :ref:`{} (curly braces) | |* noTone(): TODO | | ` |* :ref:`char ` (1 byte) | | -| | |* shiftOut(): TODO | +| | |* :ref:`shiftOut() ` | |* :ref:`// (single-line comment) |* :ref:`unsigned char | | | ` | ` (1 byte) |* pulseIn(): TODO | | | | | @@ -187,11 +187,13 @@ A more exhaustive index is available at the :ref:`language-index`. | | | | +--------------------------------------------+----------------------------------------------+---------------------------------------------------+ +.. _language-assert: + ``ASSERT(...)`` --------------- The ``ASSERT()`` function can be very useful for basic program -debugging. The function accepts a boolean; for example:: +debugging. It accepts a boolean; for example:: ASSERT(state == WAIT); @@ -255,11 +257,10 @@ Unimplemented Arduino Features The following Wiring/Arduino features are currently unimplemented on the Maple. However, they will be present in future versions: +- `tone() `_ - `noTone() `_ - `pulseIn() `_ -- `shiftOut() `_ - `String `_ -- `tone() `_ .. _our reference page: http://leaflabs.com/docs/external-interrupts/ diff --git a/wirish/io.h b/wirish/io.h index d2e4d2d..8dad1d1 100644 --- a/wirish/io.h +++ b/wirish/io.h @@ -216,5 +216,21 @@ uint8 isButtonPressed(); */ uint8 waitForButtonPress(uint32 timeout_millis); +/** + * Shift out a byte of data, one bit at a time. + * + * This function starts at either the most significant or least + * significant bit in a byte value, and shifts out each byte in order + * onto a data pin. After each bit is written to the data pin, a + * separate clock pin is pulsed to indicate that the new bit is + * available. + * + * @param dataPin Pin to shift data out on + * @param clockPin Pin to pulse after each bit is shifted out + * @param bitOrder Either MSBFIRST (big-endian) or LSBFIRST (little-endian). + * @param val Value to shift out + */ +void shiftOut(uint8 dataPin, uint8 clockPin, uint8 bitOrder, uint8 value); + #endif -- cgit v1.2.3