Forgot to add the main SPI slave interface header file in the last commit
This commit is contained in:
parent
b6d6776d02
commit
0ce50caa06
330
include/nuttx/spi/slave.h
Normal file
330
include/nuttx/spi/slave.h
Normal 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 */
|
Loading…
Reference in New Issue
Block a user