Forgot to add the main SPI slave interface header file in the last commit

This commit is contained in:
Gregory Nutt 2015-08-08 10:46:13 -06:00
parent b6d6776d02
commit 0ce50caa06

330
include/nuttx/spi/slave.h Normal file
View File

@ -0,0 +1,330 @@
/****************************************************************************
* include/nuttx/spi/slave.h
*
* Copyright(C) 2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
#ifndef __INCLUDE_NUTTX_SPI_SLAVE_H
#define __INCLUDE_NUTTX_SPI_SLAVE_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <stdint.h>
#include <stdbool.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Configuration ************************************************************/
/* CONFIG_SPI_SLAVE - Enable support for SPI slave features
* CONFIG_SPI_SLAVE_DMA - Enable support for DMA data transfers (not
* implemented in initial version).
*/
/* Access macros ************************************************************/
/****************************************************************************
* Name: SPI_SCTRLR_BIND
*
* Description:
* Bind the SPI slave device interface to the SPI slave controller
* interface and configure the SPI interface. Upon return, the
*
* Input Parameters:
* sctrlr - SPI slave controller interface instance
* sdev - SPI slave device interface instance
* mode - The SPI mode requested
* nbits - The number of bits requests.
* If value is greater > 0 then it implies MSB first
* If value is below < 0, then it implies LSB first with -nbits
*
* Returned Value:
* none
*
****************************************************************************/
#define SPI_SCTRLR_BIND(c,d,m,n) ((c)->bind(c,d,m,n))
/****************************************************************************
* Name: SPI_SCTRLR_SET_CMD/SPI_SCTRLR_SET_DATA
*
* Description:
* Set the next value to be shifted out from the interface. This primes
* the controller driver for the next transfer but has no effect on any
* in-process or currently "committed" transfers
*
* Input Parameters:
* sctrlr - SPI slave controller interface instance
* cmd - Command/data mode data value to be shifted out. The width of
* data the data must be the same as the nbits parameter previously
* provided to the bind() methos.
*
* Returned Value:
* none
*
****************************************************************************/
#define SPI_SCTRLR_SET_CMD(c,v) ((c)->set_cmd(c,v))
#define SPI_SCTRLR_SET_DATA(c,v) ((c)->set_data(c,v))
/****************************************************************************
* Name: SPI_SDEV_SELECTED
*
* Description:
* This is a SPI device callback that used when the SPI device controller
* driver detects any change in the chip select pin.
*
* Input Parameters:
* sdev - SPI device interface instance
* isselected - True: chip select is low (selected);
*
* Returned Value:
* none
*
****************************************************************************/
#define SPI_SDEV_SELECTED(d,i) ((c)->selected(d,i))
/****************************************************************************
* Name: SPI_SDEV_GET_CMD/SPI_SDEV_GET_DATA
*
* Description:
* This is a SPI device callback that used when the SPI device controller
* requires data be shifted out at the next leading clock edge. This
* is necessary to "prime the pump" so that the SPI controller driver
* can keep pace with the shifted-in data.
*
* The SPI controller driver will prime for both command and data
* transfers. Normally only LCD devices distinguish command and data.
* For devices that do not distinguish between command and data, only
* the get_cmd() method is meaningful. In that case the same function
* may be provided for get_cmd() and get_data(). Or get_data() may be
* only a stub that returns zero (it should never be called).
*
* Input Parameters:
* sdev - SPI device interface instance
*
* Returned Value:
* The next data value to be shifted out
*
****************************************************************************/
#define SPI_SDEV_GET_CMD(d,v) ((d)->get_cmd(d,v))
#define SPI_SDEV_GET_DATA(d,v) ((d)->get_data(d,v))
/****************************************************************************
* Name: SPI_SDEV_EXCHANGE_CMD/SPI_SDEV_EXCHANGE_DATA
*
* Description:
* This is a SPI device callback that used when the SPI device controller
* receives a new value shifted and requires the next value to be shifted-
* out. Notice that these values my be out of synchronization by as much
* as two words: The value to be shifted out may be two words beyond the
* value that was just shifted in.
*
* Normally only LCD devices distinguish command and data. For devices
* that do not distinguish between command and data, only the
* exchange_cmd() method is meaningful. In that case the same function
* may be provided for exchange_cmd() and exchange_data(). Or
* exchange_data() may be simply a stub that discards the shifted in
* value returns zero (it should never be called).
*
* Input Parameters:
* sdev - SPI device interface instance
* cmd - The last command/data value that was shifted in
* data
*
* Returned Value:
* The next data value to be shifted out
*
****************************************************************************/
#define SPI_SDEV_EXCHANGE_CMD(d,v) ((d)->exchange_cmd(d,v))
#define SPI_SDEV_EXCHANGE_DATA(d,v) ((d)->exchange_data(d,v))
/****************************************************************************
* Public Types
****************************************************************************/
/* There are two interfaces defined for the implementation of SPI slave:
*
* 1) struct spi_sctrlr_s - Defines one interface between the SPI
* slave device and the SPI slave controller hardware. This interface
* is implemented by the SPI slave device controller lower-half driver
* and is provided to the the SPI slave device driver when that driver
* is initialization. That SPI slave device initialization function might
* look like:
*
* int xyz_dev_initialize(FAR struct spi_sctrlr_s *sctrlr);
*
* 2) struct spi_sdev_s - Defines the second center between the SPI
* slave device and the SPI slave controller hardware. This interface
* is implemented by the SPI slave device. The slave devices passes this
* interface to the struct spi_sctrlr_s during initialization
* be calling the bind() method of the struct spi_sctrlr_s
* interface.
*
* The basic initialization steps are:
*
* 1) Board-specific logic calls board- or chip-specific logic to create an
* instance of the SPI slave controller interface, struct spi_sctrlr_s.
* 2) Board-specific logic then calls xyz_dev_initialize() to initialize
* the SPI slave device. The board-specific logic passes the instance
* of struct spi_sctrlr_s to support the initialization.
* 3) The SPI slave device driver creates and initializes an instance of
* struct spi_sdev_s; it passes this instance to the bind() method of
* of the SPI slave controller interface.
* 4) The SPI slave controller will call the slave devices get_cmd() and
* get_data() methods to get the value that will be shifted out when
* the required for the first to be word shifted out (normally all
* '0' or all '1'). The get_data() method may be the same function
* that implements the get_cmd() method if the device does not
* distinguish command and data transfers (normally only LCDs do that).
* The driver can change the next word to be shifted out at any time
* by calling the SPI slave controller's set_cmd() and set_data() method.
* 5) Upon return from the bind method, the SPI slave controller will be
* fully "armed" and ready to begin normal SPI data transfers.
*
* A typical (non-DMA) data transfer proceeds as follows:
*
* 1) Internally, the SPI slave driver detects that the SPI chip select
* has gone low, selecting this device for data transfer. If the SPI
* slave device's select method is non-NULL, the SPI slave controller
* will notify the slave device by called its selected() method.
* 2) Similarly, the SPI device driver may make a distinction between
* command and data transfer based on internal logic that is beyond
* the scope of these interface description.
* 3) As the first word is shifted in, the command or data word word
* will be shifted out. As soon as the clock is detected, the SPI
* controller driver will call the get_cmd() or get_data() method
* again to get the second word to be shifted out. NOTE: the SPI
* slave device has only one word in bit times to provide this value!
* 4) When the first word is shifted in, the SPI controller driver will
* call the device's exchange_data() or exchange_cmd() method to both
* provide the master command that was just shifted in as well to
* obtain the next value to shift out. If the SPI device responds
* with this value before clocking begins for the next word, that
* that value will be used (and the backup value obtained in 3) will
* be discarded).
* 5) The SPI device's echange_cmd/data() will will be called in a similar
* way after each subsequent word is clocked in. The only difference
* is that word returned from the previous call to exchange_cmd/data()
* will not be discard.
* 6) The activity of 5) will continue until the master raises the chip
* select signal. In that case, the SPI slave controll driver will
* again call the SPI device's selected(). At this point, the SPI
* controller driver may have two words buffered. If will discard the
* last and retain only the current word prepared to be shifted out.
* That value can be changed by the SPI device driver by calling the
* set_cmd/data() method.
*
* A typical DMA data transfer processes as follows:
* To be provided
*/
enum spi_smode_e
{
SPISLAVE_MODE0 = 0, /* CPOL=0 CHPHA=0 */
SPISLAVE_MODE1, /* CPOL=0 CHPHA=1 */
SPISLAVE_MODE2, /* CPOL=1 CHPHA=0 */
SPISLAVE_MODE3 /* CPOL=1 CHPHA=1 */
};
/* The SPI slave vtable */
struct spi_sctrlr_s;
struct spi_sdev_s;
struct spi_slaveops_s
{
CODE void (*bind)(FAR struct spi_sctrlr_s *sctrlr,
FAR spi_sdev_s *sdev, enum spi_mode_e mode, int nbits);
CODE void (*set_cmd)(FAR struct spi_sctrlr_s *sctrlr, uint16_t cmd);
CODE void (*set_data)(FAR struct spi_sctrlr_s *sctrlr, uint16_t data);
};
/* SPI private data. This structure only defines the initial fields of the
* structure visible to the SPI device drvier. The specific implementation
* may add additional, device specific fields after the vtable structure
* pointer
*/
struct spi_sctrlr_s
{
FAR const struct spi_slaveops_s *ops;
/* Private SPI slave controller driver data may follow */
};
/* The SPI slave vtable */
struct spi_sdevops_s
{
CODE void (*selected)(FAR struct spi_sdev_s *sdev, bool isselected);
CODE uint16_t (*get_cmd)(FAR struct spi_sdev_s *sdev);
CODE uint16_t (*exchange_cmd)(FAR struct spi_sdev_s *sdev), uint16_t cmd);
CODE uint16_t (*get_data)(FAR struct spi_sdev_s *sdev);
CODE uint16_t (*exchange_data)(FAR struct spi_sdev_s *sdev, uint16_t data));
};
struct spi_sdev_s
{
FAR const struct spi_sdevops_s *ops;
/* Private SPI slave device driver data may follow */
};
/****************************************************************************
* Public Data
****************************************************************************/
#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
#undef EXTERN
#if defined(__cplusplus)
}
#endif
#endif /* __INCLUDE_NUTTX_SPI_SLAVE_H */