This is intended to use in a board-specific logic and depends highly on a custom application. That's why no common driver logic is provided for now.
605 lines
22 KiB
C
605 lines
22 KiB
C
/****************************************************************************
|
|
* include/nuttx/spi/spi.h
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed with
|
|
* this work for additional information regarding copyright ownership. The
|
|
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
|
* "License"); you may not use this file except in compliance with the
|
|
* License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
* License for the specific language governing permissions and limitations
|
|
* under the License.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifndef __INCLUDE_NUTTX_SPI_SPI_H
|
|
#define __INCLUDE_NUTTX_SPI_SPI_H
|
|
|
|
/****************************************************************************
|
|
* Included Files
|
|
****************************************************************************/
|
|
|
|
#include <nuttx/config.h>
|
|
|
|
#include <sys/types.h>
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
#include <errno.h>
|
|
|
|
/****************************************************************************
|
|
* Pre-processor Definitions
|
|
****************************************************************************/
|
|
|
|
/* Configuration ************************************************************/
|
|
|
|
/* These SPI configuration options affect the form of the SPI interface:
|
|
*
|
|
* CONFIG_SPI_EXCHANGE - Driver supports a single exchange method
|
|
* (vs a recvblock() and sndblock() methods).
|
|
* CONFIG_SPI_CMDDATA - Devices on the SPI bus require out-of-band support
|
|
* to distinguish command transfers from data transfers. Such devices
|
|
* will often support either 9-bit SPI (yech) or 8-bit SPI and a GPIO
|
|
* output that selects between command and data.
|
|
* CONFIG_SPI_HWFEATURES - Include an interface method to support special,
|
|
* hardware-specific SPI features.
|
|
*/
|
|
|
|
/* Access macros ************************************************************/
|
|
|
|
/****************************************************************************
|
|
* Name: SPI_LOCK
|
|
*
|
|
* Description:
|
|
* On SPI buses where there are multiple devices, it will be necessary to
|
|
* lock SPI to have exclusive access to the buses for a sequence of
|
|
* transfers. The bus should be locked before the chip is selected. After
|
|
* locking the SPI bus, the caller should then also call the setfrequency,
|
|
* setbits, and setmode methods to make sure that the SPI is properly
|
|
* configured for the device. If the SPI bus is being shared, then it
|
|
* may have been left in an incompatible state.
|
|
*
|
|
* Input Parameters:
|
|
* dev - Device-specific state data
|
|
* lock - true: Lock spi bus, false: unlock SPI bus
|
|
*
|
|
* Returned Value:
|
|
* None
|
|
*
|
|
****************************************************************************/
|
|
|
|
#define SPI_LOCK(d,l) (d)->ops->lock(d,l)
|
|
|
|
/****************************************************************************
|
|
* Name: SPI_SELECT
|
|
*
|
|
* Description:
|
|
* Enable/disable the SPI chip select. The implementation of this method
|
|
* must include handshaking: If a device is selected, it must hold off
|
|
* all other attempts to select the device until the device is deselected.
|
|
* Required.
|
|
*
|
|
* Input Parameters:
|
|
* dev - Device-specific state data
|
|
* devid - Identifies the device to select
|
|
* selected - true: slave selected, false: slave de-selected
|
|
*
|
|
* Returned Value:
|
|
* None
|
|
*
|
|
****************************************************************************/
|
|
|
|
#define SPI_SELECT(d,id,s) ((d)->ops->select(d,id,s))
|
|
|
|
/****************************************************************************
|
|
* Name: SPI_SETFREQUENCY
|
|
*
|
|
* Description:
|
|
* Set the SPI frequency. Required.
|
|
*
|
|
* Input Parameters:
|
|
* dev - Device-specific state data
|
|
* frequency - The SPI frequency requested
|
|
*
|
|
* Returned Value:
|
|
* Returns the actual frequency selected
|
|
*
|
|
****************************************************************************/
|
|
|
|
#define SPI_SETFREQUENCY(d,f) ((d)->ops->setfrequency(d,f))
|
|
|
|
/****************************************************************************
|
|
* Name: SPI_SETDELAY
|
|
*
|
|
* Description:
|
|
* Set the SPI Delays in nanoseconds. Optional.
|
|
*
|
|
* Input Parameters:
|
|
* dev - Device-specific state data
|
|
* startdelay - The delay between CS active and first CLK
|
|
* stopdelay - The delay between last CLK and CS inactive
|
|
* csdelay - The delay between CS inactive and CS active again
|
|
* ifdelay - The delay between frames
|
|
*
|
|
* Returned Value:
|
|
* Returns zero (OK) on success; a negated errno value is return on any
|
|
* failure.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifdef CONFIG_SPI_DELAY_CONTROL
|
|
# define SPI_SETDELAY(d,a,b,c,i) ((d)->ops->setdelay(d,a,b,c,i))
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: SPI_SETMODE
|
|
*
|
|
* Description:
|
|
* Set the SPI mode. Optional. See enum spi_mode_e for mode definitions.
|
|
*
|
|
* Input Parameters:
|
|
* dev - Device-specific state data
|
|
* mode - The SPI mode requested
|
|
*
|
|
* Returned Value:
|
|
* none
|
|
*
|
|
****************************************************************************/
|
|
|
|
#define SPI_SETMODE(d,m) \
|
|
do { if ((d)->ops->setmode) (d)->ops->setmode(d,m); } while (0)
|
|
|
|
/****************************************************************************
|
|
* Name: SPI_SETBITS
|
|
*
|
|
* Description:
|
|
* Set the number of bits per word.
|
|
*
|
|
* Input Parameters:
|
|
* dev - Device-specific state data
|
|
* nbits - The number of bits in an SPI word.
|
|
*
|
|
* Returned Value:
|
|
* none
|
|
*
|
|
****************************************************************************/
|
|
|
|
#define SPI_SETBITS(d,b) \
|
|
do { if ((d)->ops->setbits) (d)->ops->setbits(d,b); } while (0)
|
|
|
|
/****************************************************************************
|
|
* Name: SPI_HWFEATURES
|
|
*
|
|
* Description:
|
|
* Set hardware-specific feature flags.
|
|
*
|
|
* Input Parameters:
|
|
* dev - Device-specific state data
|
|
* features - H/W feature flags
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) if the selected H/W features are enabled; A negated errno
|
|
* value if any H/W feature is not supportable.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifdef CONFIG_SPI_HWFEATURES
|
|
/* If there are multiple SPI drivers, some may not support hardware
|
|
* feature selection.
|
|
*/
|
|
|
|
# define SPI_HWFEATURES(d,f) \
|
|
(((d)->ops->hwfeatures) ? (d)->ops->hwfeatures(d,f) : ((f) == 0 ? OK : -ENOSYS))
|
|
|
|
/* These are currently defined feature flags:
|
|
*
|
|
* Bit 0: HWFEAT_CRCGENERATION
|
|
* Hardware CRC generation
|
|
* Bit 1: HWFEAT_FORCE_CS_INACTIVE_AFTER_TRANSFER
|
|
* CS rises after every Transmission, also if we provide new data
|
|
* immediately
|
|
* Bit 2: HWFEAT_FORCE_CS_ACTIVE_AFTER_TRANSFER
|
|
* CS does not rise automatically after a transmission, also if
|
|
* the spi runs out of data (for a long time)
|
|
* Bit 3: HWFEAT_ESCAPE_LASTXFER
|
|
* Do not set the LASTXFER-Bit at the last word of the next
|
|
* exchange, Flag is auto-resetting after the next LASTXFER
|
|
* condition. (see spi_exchange)
|
|
* Bit 4: HWFEAT_LSBFIRST
|
|
* Data transferred LSB first (default is MSB first)
|
|
* Bit 5: Turn deferred trigger mode on or off. Primarily used for DMA
|
|
* mode. If a transfer is deferred then the DMA will not actually
|
|
* be triggered until a subsequent call to SPI_TRIGGER to set it
|
|
* off.
|
|
*/
|
|
|
|
# ifdef CONFIG_SPI_CRCGENERATION
|
|
# define HWFEAT_CRCGENERATION (1 << 0)
|
|
# endif
|
|
|
|
# ifdef CONFIG_SPI_CS_CONTROL
|
|
# define HWFEAT_FORCE_CS_CONTROL_MASK (7 << 1)
|
|
# define HWFEAT_FORCE_CS_INACTIVE_AFTER_TRANSFER (1 << 1)
|
|
# define HWFEAT_FORCE_CS_ACTIVE_AFTER_TRANSFER (1 << 2)
|
|
# define HWFEAT_ESCAPE_LASTXFER (1 << 3)
|
|
# endif
|
|
|
|
# ifdef CONFIG_SPI_BITORDER
|
|
# define HWFEAT_MSBFIRST (0 << 4)
|
|
# define HWFEAT_LSBFIRST (1 << 4)
|
|
# endif
|
|
|
|
# ifdef CONFIG_SPI_TRIGGER
|
|
# define HWFEAT_TRIGGER (1 << 5)
|
|
# endif
|
|
|
|
#else
|
|
/* Any attempt to select hardware features with CONFIG_SPI_HWFEATURES
|
|
* deselected will return an -ENOSYS error.
|
|
*/
|
|
|
|
# define SPI_HWFEATURES(d,f) (((f) == 0) ? OK : -ENOSYS)
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: SPI_STATUS
|
|
*
|
|
* Description:
|
|
* Get SPI/MMC status. Optional.
|
|
*
|
|
* Input Parameters:
|
|
* dev - Device-specific state data
|
|
* devid - Identifies the device to report status on
|
|
*
|
|
* Returned Value:
|
|
* Returns a bitset of status values (see SPI_STATUS_* defines)
|
|
*
|
|
****************************************************************************/
|
|
|
|
#define SPI_STATUS(d,id) \
|
|
((d)->ops->status ? (d)->ops->status(d, id) : SPI_STATUS_PRESENT)
|
|
|
|
/* SPI status bits -- Some dedicated for SPI MMC/SD support and may have no
|
|
* relationship to SPI other than needed by the SPI MMC/SD interface
|
|
*/
|
|
|
|
#define SPI_STATUS_PRESENT 0x01 /* Bit 0=1: MMC/SD card present */
|
|
#define SPI_STATUS_WRPROTECTED 0x02 /* Bit 1=1: MMC/SD card write protected */
|
|
|
|
/****************************************************************************
|
|
* Name: SPI_CMDDATA
|
|
*
|
|
* Description:
|
|
* Some devices require an additional out-of-band bit to specify if the
|
|
* next word sent to the device is a command or data. This is typical, for
|
|
* example, in "9-bit" displays where the 9th bit is the CMD/DATA bit.
|
|
* This function provides selection of command or data.
|
|
*
|
|
* This "latches" the CMD/DATA state. It does not have to be called before
|
|
* every word is transferred; only when the CMD/DATA state changes. This
|
|
* method is required if CONFIG_SPI_CMDDATA is selected in the NuttX
|
|
* configuration
|
|
*
|
|
* Input Parameters:
|
|
* dev - Device-specific state data
|
|
* cmd - TRUE: The following word is a command; FALSE: the following words
|
|
* are data.
|
|
*
|
|
* Returned Value:
|
|
* OK unless an error occurs. Then a negated errno value is returned
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifdef CONFIG_SPI_CMDDATA
|
|
# define SPI_CMDDATA(d,id,cmd) ((d)->ops->cmddata(d,id,cmd))
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: SPI_SEND
|
|
*
|
|
* Description:
|
|
* Exchange one word on SPI. Required.
|
|
*
|
|
* Input Parameters:
|
|
* dev - Device-specific state data
|
|
* wd - The word to send. The size of the data is determined by the
|
|
* number of bits selected for the SPI interface.
|
|
*
|
|
* Returned Value:
|
|
* Received value
|
|
*
|
|
****************************************************************************/
|
|
|
|
#define SPI_SEND(d,wd) ((d)->ops->send(d,(uint16_t)(wd)))
|
|
|
|
/****************************************************************************
|
|
* Name: SPI_SNDBLOCK
|
|
*
|
|
* Description:
|
|
* Send a block of data on SPI. Required.
|
|
*
|
|
* Input Parameters:
|
|
* dev - Device-specific state data
|
|
* buffer - A pointer to the buffer of data to be sent
|
|
* nwords - The length of data to send from the buffer in number of words.
|
|
* The wordsize is determined by the number of bits-per-word
|
|
* selected for the SPI interface. If nbits <= 8, the data is
|
|
* packed into uint8_t's; if nbits >8, the data is packed into
|
|
* uint16_t's
|
|
*
|
|
* Returned Value:
|
|
* None
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifdef CONFIG_SPI_EXCHANGE
|
|
# define SPI_SNDBLOCK(d,b,l) ((d)->ops->exchange(d,b,0,l))
|
|
#else
|
|
# define SPI_SNDBLOCK(d,b,l) ((d)->ops->sndblock(d,b,l))
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: SPI_RECVBLOCK
|
|
*
|
|
* Description:
|
|
* Receive a block of data from SPI. Required.
|
|
*
|
|
* Input Parameters:
|
|
* dev - Device-specific state data
|
|
* buffer - A pointer to the buffer in which to receive data
|
|
* nwords - The length of data that can be received in the buffer in number
|
|
* of words. The wordsize is determined by the number of bits-
|
|
* per-word selected for the SPI interface. If nbits <= 8, the
|
|
* data is packed into uint8_t's; if nbits > 8, the data is packed
|
|
* into uint16_t's
|
|
*
|
|
* Returned Value:
|
|
* None
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifdef CONFIG_SPI_EXCHANGE
|
|
# define SPI_RECVBLOCK(d,b,l) ((d)->ops->exchange(d,0,b,l))
|
|
#else
|
|
# define SPI_RECVBLOCK(d,b,l) ((d)->ops->recvblock(d,b,l))
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: SPI_EXCHANGE
|
|
*
|
|
* Description:
|
|
* Exchange a block of data from SPI. Required.
|
|
*
|
|
* Input Parameters:
|
|
* dev - Device-specific state data
|
|
* txbuffer - A pointer to the buffer of data to be sent
|
|
* rxbuffer - A pointer to the buffer in which to receive data
|
|
* nwords - The length of data to be exchanged in units of words. The
|
|
* wordsize is determined by the number of bits-per-word
|
|
* selected for the SPI interface. If nbits <= 8, the data is
|
|
* packed into uint8_t's; if nbits >8, the data is packed into
|
|
* uint16_t's
|
|
*
|
|
* Returned Value:
|
|
* None
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifdef CONFIG_SPI_EXCHANGE
|
|
# define SPI_EXCHANGE(d,t,r,l) ((d)->ops->exchange(d,t,r,l))
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: SPI_REGISTERCALLBACK
|
|
*
|
|
* Description:
|
|
* Register a callback that will be invoked on any media status change
|
|
* (i.e, anything that would be reported differently by SPI_STATUS).
|
|
* Optional
|
|
*
|
|
* Input Parameters:
|
|
* dev - Device-specific state data
|
|
* callback - The function to call on the media change
|
|
* arg - A caller provided value to return with the callback
|
|
*
|
|
* Returned Value:
|
|
* 0 on success; negated errno on failure.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#define SPI_REGISTERCALLBACK(d,c,a) \
|
|
((d)->ops->registercallback ? (d)->ops->registercallback(d,c,a) : -ENOSYS)
|
|
|
|
/****************************************************************************
|
|
* Name: SPI_TRIGGER
|
|
*
|
|
* Description:
|
|
* Trigger a previously configured DMA transfer.
|
|
*
|
|
* Input Parameters:
|
|
* dev - Device-specific state data
|
|
*
|
|
* Returned Value:
|
|
* OK - Trigger was fired
|
|
* -ENOSYS - Trigger not fired due to lack of DMA or low level support
|
|
* -EIO - Trigger not fired because not previously primed
|
|
*
|
|
****************************************************************************/
|
|
|
|
# define SPI_TRIGGER(d) \
|
|
(((d)->ops->trigger) ? ((d)->ops->trigger(d)) : -ENOSYS)
|
|
|
|
/* SPI Device Macros ********************************************************/
|
|
|
|
/* This builds a SPI devid from its type and index */
|
|
|
|
#define SPIDEV_ID(type,index) ((((uint32_t)(type) & 0xffff) << 16) | \
|
|
((uint32_t)(index) & 0xffff))
|
|
|
|
/* This retrieves the fields from a SPI devid */
|
|
|
|
#define SPIDEVID_TYPE (devid) (((uint32_t)(devid) >> 16) & 0xffff)
|
|
#define SPIDEVID_INDEX(devid) ((uint32_t)(devid) & 0xffff)
|
|
|
|
/* These are standard definitions for the defined SPI device IDs. The index
|
|
* argument, n, is the instance number. This should be zero if there is
|
|
* only one instance of the SPI device on the SPI bus. Indices greater than
|
|
* zero discriminate the additional devices of the same type on the SPI bus.
|
|
*/
|
|
|
|
#define SPIDEV_NONE(n) SPIDEV_ID(SPIDEVTYPE_NONE, (n))
|
|
#define SPIDEV_MMCSD(n) SPIDEV_ID(SPIDEVTYPE_MMCSD, (n))
|
|
#define SPIDEV_FLASH(n) SPIDEV_ID(SPIDEVTYPE_FLASH, (n))
|
|
#define SPIDEV_ETHERNET(n) SPIDEV_ID(SPIDEVTYPE_ETHERNET, (n))
|
|
#define SPIDEV_DISPLAY(n) SPIDEV_ID(SPIDEVTYPE_DISPLAY, (n))
|
|
#define SPIDEV_CAMERA(n) SPIDEV_ID(SPIDEVTYPE_CAMERA, (n))
|
|
#define SPIDEV_WIRELESS(n) SPIDEV_ID(SPIDEVTYPE_WIRELESS, (n))
|
|
#define SPIDEV_TOUCHSCREEN(n) SPIDEV_ID(SPIDEVTYPE_TOUCHSCREEN, (n))
|
|
#define SPIDEV_EXPANDER(n) SPIDEV_ID(SPIDEVTYPE_EXPANDER, (n))
|
|
#define SPIDEV_MUX(n) SPIDEV_ID(SPIDEVTYPE_MUX, (n))
|
|
#define SPIDEV_AUDIO_DATA(n) SPIDEV_ID(SPIDEVTYPE_AUDIO_DATA, (n))
|
|
#define SPIDEV_AUDIO_CTRL(n) SPIDEV_ID(SPIDEVTYPE_AUDIO_CTRL, (n))
|
|
#define SPIDEV_EEPROM(n) SPIDEV_ID(SPIDEVTYPE_EEPROM, (n))
|
|
#define SPIDEV_ACCELEROMETER(n) SPIDEV_ID(SPIDEVTYPE_ACCELEROMETER, (n))
|
|
#define SPIDEV_BAROMETER(n) SPIDEV_ID(SPIDEVTYPE_BAROMETER, (n))
|
|
#define SPIDEV_TEMPERATURE(n) SPIDEV_ID(SPIDEVTYPE_TEMPERATURE, (n))
|
|
#define SPIDEV_IEEE802154(n) SPIDEV_ID(SPIDEVTYPE_IEEE802154, (n))
|
|
#define SPIDEV_CONTACTLESS(n) SPIDEV_ID(SPIDEVTYPE_CONTACTLESS, (n))
|
|
#define SPIDEV_CANBUS(n) SPIDEV_ID(SPIDEVTYPE_CANBUS, (n))
|
|
#define SPIDEV_USBHOST(n) SPIDEV_ID(SPIDEVTYPE_USBHOST, (n))
|
|
#define SPIDEV_LPWAN(n) SPIDEV_ID(SPIDEVTYPE_LPWAN, (n))
|
|
#define SPIDEV_ADC(n) SPIDEV_ID(SPIDEVTYPE_ADC, (n))
|
|
#define SPIDEV_MOTOR(n) SPIDEV_ID(SPIDEVTYPE_MOTOR, (n))
|
|
#define SPIDEV_USER(n) SPIDEV_ID(SPIDEVTYPE_USER, (n))
|
|
|
|
/****************************************************************************
|
|
* Public Types
|
|
****************************************************************************/
|
|
|
|
/* The type of the media change callback function */
|
|
|
|
typedef CODE void (*spi_mediachange_t)(FAR void *arg);
|
|
|
|
/* If the board supports multiple SPI devices types, this enumeration
|
|
* identifies which is selected or de-selected.
|
|
* There may be more than one instance of each type on a bus, see below.
|
|
*/
|
|
|
|
enum spi_devtype_e
|
|
{
|
|
SPIDEVTYPE_NONE = 0, /* Not a valid value */
|
|
SPIDEVTYPE_MMCSD, /* Select SPI MMC/SD device */
|
|
SPIDEVTYPE_FLASH, /* Select SPI FLASH device */
|
|
SPIDEVTYPE_ETHERNET, /* Select SPI Ethernet device */
|
|
SPIDEVTYPE_DISPLAY, /* Select SPI LCD/OLED display device */
|
|
SPIDEVTYPE_CAMERA, /* Select SPI imaging device */
|
|
SPIDEVTYPE_WIRELESS, /* Select SPI Wireless device */
|
|
SPIDEVTYPE_TOUCHSCREEN, /* Select SPI touchscreen device */
|
|
SPIDEVTYPE_EXPANDER, /* Select SPI I/O expander device */
|
|
SPIDEVTYPE_MUX, /* Select SPI multiplexer device */
|
|
SPIDEVTYPE_AUDIO_DATA, /* Select SPI audio codec device data port */
|
|
SPIDEVTYPE_AUDIO_CTRL, /* Select SPI audio codec device control port */
|
|
SPIDEVTYPE_EEPROM, /* Select SPI EEPROM device */
|
|
SPIDEVTYPE_ACCELEROMETER, /* Select SPI Accelerometer device */
|
|
SPIDEVTYPE_BAROMETER, /* Select SPI Pressure/Barometer device */
|
|
SPIDEVTYPE_TEMPERATURE, /* Select SPI Temperature sensor device */
|
|
SPIDEVTYPE_IEEE802154, /* Select SPI IEEE 802.15.4 wireless device */
|
|
SPIDEVTYPE_CONTACTLESS, /* Select SPI Contactless device */
|
|
SPIDEVTYPE_CANBUS, /* Select SPI CAN bus controller over SPI */
|
|
SPIDEVTYPE_USBHOST, /* Select SPI USB host controller over SPI */
|
|
SPIDEVTYPE_LPWAN, /* Select SPI LPWAN controller over SPI */
|
|
SPIDEVTYPE_ADC, /* Select SPI ADC device */
|
|
SPIDEVTYPE_MOTOR, /* Select SPI motor device */
|
|
SPIDEVTYPE_USER /* Board-specific values start here
|
|
* This must always be the last definition. */
|
|
};
|
|
|
|
/* Certain SPI devices may required different clocking modes */
|
|
|
|
enum spi_mode_e
|
|
{
|
|
SPIDEV_MODE0 = 0, /* CPOL=0 CPHA=0 */
|
|
SPIDEV_MODE1, /* CPOL=0 CPHA=1 */
|
|
SPIDEV_MODE2, /* CPOL=1 CPHA=0 */
|
|
SPIDEV_MODE3, /* CPOL=1 CPHA=1 */
|
|
SPIDEV_MODETI, /* CPOL=0 CPHA=1 TI Synchronous Serial Frame Format */
|
|
};
|
|
|
|
#ifdef CONFIG_SPI_HWFEATURES
|
|
/* This is a type wide enough to support all hardware features */
|
|
|
|
typedef uint8_t spi_hwfeatures_t;
|
|
#endif
|
|
|
|
/* The SPI vtable */
|
|
|
|
struct spi_dev_s;
|
|
struct spi_ops_s
|
|
{
|
|
CODE int (*lock)(FAR struct spi_dev_s *dev, bool lock);
|
|
CODE void (*select)(FAR struct spi_dev_s *dev, uint32_t devid,
|
|
bool selected);
|
|
CODE uint32_t (*setfrequency)(FAR struct spi_dev_s *dev,
|
|
uint32_t frequency);
|
|
#ifdef CONFIG_SPI_DELAY_CONTROL
|
|
CODE int (*setdelay)(FAR struct spi_dev_s *dev, uint32_t a,
|
|
uint32_t b, uint32_t c, uint32_t i);
|
|
#endif
|
|
CODE void (*setmode)(FAR struct spi_dev_s *dev, enum spi_mode_e mode);
|
|
CODE void (*setbits)(FAR struct spi_dev_s *dev, int nbits);
|
|
#ifdef CONFIG_SPI_HWFEATURES
|
|
CODE int (*hwfeatures)(FAR struct spi_dev_s *dev,
|
|
spi_hwfeatures_t features);
|
|
#endif
|
|
CODE uint8_t (*status)(FAR struct spi_dev_s *dev, uint32_t devid);
|
|
#ifdef CONFIG_SPI_CMDDATA
|
|
CODE int (*cmddata)(FAR struct spi_dev_s *dev, uint32_t devid,
|
|
bool cmd);
|
|
#endif
|
|
CODE uint32_t (*send)(FAR struct spi_dev_s *dev, uint32_t wd);
|
|
#ifdef CONFIG_SPI_EXCHANGE
|
|
CODE void (*exchange)(FAR struct spi_dev_s *dev,
|
|
FAR const void *txbuffer, FAR void *rxbuffer,
|
|
size_t nwords);
|
|
#else
|
|
CODE void (*sndblock)(FAR struct spi_dev_s *dev,
|
|
FAR const void *buffer, size_t nwords);
|
|
CODE void (*recvblock)(FAR struct spi_dev_s *dev, FAR void *buffer,
|
|
size_t nwords);
|
|
#endif
|
|
#ifdef CONFIG_SPI_TRIGGER
|
|
CODE int (*trigger)(FAR struct spi_dev_s *dev);
|
|
#endif
|
|
CODE int (*registercallback)(FAR struct spi_dev_s *dev,
|
|
spi_mediachange_t callback, void *arg);
|
|
};
|
|
|
|
/* SPI private data. This structure only defines the initial fields of the
|
|
* structure visible to the SPI client. The specific implementation may
|
|
* add additional, device specific fields
|
|
*/
|
|
|
|
struct spi_dev_s
|
|
{
|
|
FAR const struct spi_ops_s *ops;
|
|
};
|
|
|
|
#undef EXTERN
|
|
#if defined(__cplusplus)
|
|
#define EXTERN extern "C"
|
|
extern "C"
|
|
{
|
|
#else
|
|
#define EXTERN extern
|
|
#endif
|
|
|
|
#undef EXTERN
|
|
#if defined(__cplusplus)
|
|
}
|
|
#endif
|
|
#endif /* __INCLUDE_NUTTX_SPI_SPI_H */
|