From 7cd5350622f5c7c84662beaee5b92a362be0f59b Mon Sep 17 00:00:00 2001 From: Marti Bolivar Date: Thu, 28 Apr 2011 13:52:58 -0400 Subject: SPI refactor. Still a polling driver, but the libmaple proper interface exposes enough that users enable the various interrupts and define their own IRQ handlers if they feel like it. Wirish HardwareSPI interface was largely redone; it's more like the Arduino implementation now, although there are some differences when I didn't like their API. The old methods are still there, but are deprecated and slated for deletion in 0.1.0. New board-specific values: BOARD_NR_SPI, BOARD_SPIx_NSS_PIN, BOARD_SPIx_MOSI_PIN, BOARD_SPIx_MISO_PIN, and BOARD_SPIx_SCK_PIN, for x from 1 to BOARD_NR_SPI. Documentation was updated appropriately. --- docs/source/lang/api/hardwarespi.rst | 215 ++++++++++++++++++----------------- docs/source/spi.rst | 6 +- 2 files changed, 109 insertions(+), 112 deletions(-) (limited to 'docs/source') diff --git a/docs/source/lang/api/hardwarespi.rst b/docs/source/lang/api/hardwarespi.rst index 53a225d..289ded5 100644 --- a/docs/source/lang/api/hardwarespi.rst +++ b/docs/source/lang/api/hardwarespi.rst @@ -5,160 +5,161 @@ HardwareSPI =========== -This class is used for creating objects to manage the Maple's built-in -SPI ports. The Maple has two SPI ports. The relevant pins -corresponding to each port's logic signals are documented in the -following table (and on the Maple silkscreen): +This page describes how to use the built-in SPI ports. It does not +describe the SPI protocol itself. For more information about SPI, see +the :ref:`SPI reference `. -.. _lang-hardwarespi-pinout: +.. contents:: Contents + :local: -.. list-table:: - :header-rows: 1 +Getting Started +--------------- - * - Port number - - NSS - - MOSI - - MISO - - SCK +.. TODO [0.1.0] Add a note about calling disableDebugPorts() when +.. using SPI3 on Maple Native - * - 1 - - 10 - - 11 - - 12 - - 13 +In order to get started, you'll first need to define a ``HardwareSPI`` +variable, which you'll use to control the SPI port. Do this by +putting the line "``HardwareSPI spi(number);``" with your variables, +where ``number`` is the SPI port's number. - * - 2 - - 31 - - 32 - - 33 - - 34 +Here's an example (we'll fill in :ref:`setup() ` and +:ref:`loop() ` later):: -If you use a SPI port, you cannot simultaneously use its associated -pins for other purposes. + // Use SPI port number 1 + HardwareSPI spi(1); -Library Documentation ---------------------- + void setup() { + // Your setup code + } + + void loop() { + // Do stuff with SPI + } -Using the SPI Class -^^^^^^^^^^^^^^^^^^^ +Turning the SPI Port On +----------------------- -You can declare that you want to use SPI in your sketch by putting -``HardwareSPI Spi(number);`` with your variables, where ``number`` is -1 or 2, depending on which SPI you want to use. Then you can use the -functions described in the next section. For example:: +Now it's time to turn your SPI port on. Do this with the ``begin()`` +function (an example is given below). - // Use SPI 1 - HardwareSpi Spi(1); +.. FIXME [0.0.10] Breathe doesn't include the class; fix & submit pull req + +.. doxygenfunction:: HardwareSPI::begin + +The speed at which the SPI port communicates is configured using a +``SPIFrequency`` value: + +.. FIXME [0.1.0] Breathe's enum output is enormous; shrink & submit pull req + +.. doxygenenum:: SPIFrequency + +.. note:: Due to hardware issues, you can't use the frequency + ``SPI_140_625KHz`` with SPI port 1. + +You'll need to determine the correct values for ``frequency``, +``bitOrder``, and ``mode`` yourself, by consulting the datasheet for +the device you're communicating with. Continuing our example from +before, we'll add a call to ``begin()`` to our ``setup()``:: + + // Use SPI port number 1 + HardwareSPI spi(1); void setup() { - Spi.begin(SPI_18MHZ); + // Turn on the SPI port + spi.begin(SPI_18MHZ, MSBFIRST, 0); } void loop() { - // Get the next byte from the peripheral - uint8 byte = Spi.recv(); + // Do stuff with SPI } -HardwareSPI Class Reference -^^^^^^^^^^^^^^^^^^^^^^^^^^^ +If you call ``begin()`` with no arguments (as in "``spi.begin();``"), +it's the same as if you wrote "``spi.begin(SPI_1_125MHZ, MSBFIRST, +0);``". -.. cpp:class:: HardwareSPI +Communicating Over SPI +---------------------- - Class for interacting with SPI. +Now that you've got your SPI port set up, it's time to start +communicating. You can send data using ``HardwareSPI::write()``, +receive data using ``HardwareSPI::read()``, and do both using +``HardwareSPI::transfer()``. -.. cpp:function:: HardwareSPI::HardwareSPI(uint32 spi_num) +.. cpp:function:: void HardwareSPI::write(byte data) - Construct an object for managing a SPI peripheral. ``spi_num`` - must be 1 or 2; see the :ref:`table above - ` for pinout information. + Send a single byte of data. -.. cpp:function:: void HardwareSPI::begin(SPIFrequency freq, uint32 endianness, uint32 mode) + **Parameters**: - Configure the baudrate of the given SPI port and set up the header - pins appropriately. + - ``data``: Byte to send - Parameters: +.. cpp:function:: byte HardwareSPI::read() - - ``freq``: one of the ``SPIFrequency`` values, given :ref:`below - `. + Get the next available, unread byte. If there aren't any unread + bytes, this function will wait until one is received. - - ``endianness``: either ``LSBFIRST`` (little-endian) or - ``MSBFIRST`` (big-endian). +.. cpp:function:: byte HardwareSPI::transmit(byte data) - - ``mode``: one of 0, 1, 2, or 3, and specifies which SPI mode is - used. The mode number determines a combination of polarity and - phase according to the following table: + Send a byte, then return the next byte received. - .. list-table:: - :header-rows: 1 + **Parameters:** - * - Mode - - Polarity - - Phase + - ``data``: Byte to send - * - 0 - - 0 - - 0 + **Returns:** Next unread byte - * - 1 - - 0 - - 1 +Continuing our example from before, let's send a number over SPI and +print out whatever we get back over :ref:`lang-serialusb`:: - * - 2 - - 1 - - 0 + // Use SPI port number 1 + HardwareSPI spi(1); - * - 3 - - 1 - - 1 + void setup() { + // Turn on the SPI port + spi.begin(SPI_18MHZ, MSBFIRST, 0); + } - For more information on polarity and phase, see the - :ref:`external references, below `. + void loop() { + // Send 245 over SPI, and wait for a response. + spi.write(245); + byte response = spi.read(); + // Print out the response received. + SerialUSB.print("response: "); + SerialUSB.println(response, DEC); + } + +HardwareSPI Class Reference +--------------------------- + +There are a number of other things you can accomplish with your +``spi`` object. A full function listing follows. -.. cpp:function:: void HardwareSPI::begin() +.. doxygenclass:: HardwareSPI + :members: HardwareSPI, begin, beginSlave, end, read, write, transfer - A convenience ``begin()``, equivalent to ``begin(SPI_1_125MHZ, - MSBFIRST, 0)``. +Deprecated Functions +-------------------- -.. cpp:function:: uint8 HardwareSpi::send(uint8 *data, uint32 length) +The following functions are defined for now, but they have been +deprecated, and will be removed in a future Maple IDE release. You +shouldn't use them in new programs, and you should change any of your +programs which do use them to the up-to-date functions discussed +above. + +.. cpp:function:: uint8 HardwareSPI::send(uint8 *data, uint32 length) Writes ``data`` into the port buffer to be transmitted as soon as possible, where ``length`` is the number of bytes to send from ``data``. Returns the last byte shifted back from slave. -.. cpp:function:: uint8 HardwareSpi::send(uint8 data) +.. cpp:function:: uint8 HardwareSPI::send(uint8 data) Writes the single byte ``data`` into the port buffer to be transmitted as soon as possible. Returns the data byte shifted back from the slave. -.. cpp:function:: uint8 HardwareSpi::recv() +.. cpp:function:: uint8 HardwareSPI::recv() Reads a byte from the peripheral. Returns the next byte in the buffer. - -SPI Speeds -^^^^^^^^^^ - -.. _lang-hardwarespi-spifrequency: - -The possible SPI speeds are configured using the ``SPIFrequency`` enum: - -.. doxygenenum:: SPIFrequency - -.. _lang-hardwarespi-seealso: - -See Also --------- - -* `Wikipedia Article on Serial Peripheral Interface Bus (SPI) - `_ -* `Arduino reference on SPI - `_ -* `Hardcore SPI on Arduino `_ by kik64 -* STMicro documentation for STM32F103RB microcontroller: - - * `Datasheet `_ (pdf) - * `Reference Manual `_ (pdf) - - diff --git a/docs/source/spi.rst b/docs/source/spi.rst index 2da4bf8..dd9f1f5 100644 --- a/docs/source/spi.rst +++ b/docs/source/spi.rst @@ -8,12 +8,8 @@ The Serial Peripheral Interface Bus (SPI) is a serial data transfer protocol useful for interacting with a wide variety of hardware peripherals. -The Maple has two SPI ports. The first has NSS on D10, MOSI on -D11, MISO on D12, and SCK on D13. The second has NSS on D31, SCK on -D32, MISO on D33, and MOSI on D34. - The public libmaple API for managing the SPI ports is the -:ref:`HardwareSpi ` class. +:ref:`HardwareSPI ` class. Recommended Reading ------------------- -- cgit v1.2.3