incubator-nuttx/include/nuttx/spi/qspi.h

366 lines
12 KiB
C

/****************************************************************************
* include/nuttx/spi/qspi.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_QSPI_H
#define __INCLUDE_NUTTX_SPI_QSPI_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <stdint.h>
#include <stdbool.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Access macros ************************************************************/
/****************************************************************************
* Name: QSPI_LOCK
*
* Description:
* On QSPI buses where there are multiple devices, it will be necessary to
* lock QSPI 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 QSPI bus, the caller should then also call the setfrequency,
* setbits, and setmode methods to make sure that the QSPI is properly
* configured for the device. If the QSPI bus is being shared, then it
* may have been left in an incompatible state.
*
* Input Parameters:
* dev - Device-specific state data
* lock - true: Lock qspi bus, false: unlock QSPI bus
*
* Returned Value:
* None
*
****************************************************************************/
#define QSPI_LOCK(d,l) (d)->ops->lock(d,l)
/****************************************************************************
* Name: QSPI_SETFREQUENCY
*
* Description:
* Set the QSPI frequency. Required.
*
* Input Parameters:
* dev - Device-specific state data
* frequency - The QSPI frequency requested
*
* Returned Value:
* Returns the actual frequency selected
*
****************************************************************************/
#define QSPI_SETFREQUENCY(d,f) ((d)->ops->setfrequency(d,f))
/****************************************************************************
* Name: QSPI_SETMODE
*
* Description:
* Set the QSPI mode. Optional. See enum qspi_mode_e for mode definitions.
*
* Input Parameters:
* dev - Device-specific state data
* mode - The QSPI mode requested
*
* Returned Value:
* none
*
****************************************************************************/
#define QSPI_SETMODE(d,m) (d)->ops->setmode(d,m)
/****************************************************************************
* Name: QSPI_SETBITS
*
* Description:
* Set the number if bits per word.
*
* Input Parameters:
* dev - Device-specific state data
* 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 QSPI_SETBITS(d,b) (d)->ops->setbits(d,b)
/****************************************************************************
* Name: QSPI_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_QSPI_HWFEATURES
/* If there are multiple QSPI drivers, some may not support hardware
* feature selection.
*/
# define QSPI_HWFEATURES(d,f) \
(((d)->ops->hwfeatures) ? (d)->ops->hwfeatures(d,f) : ((f) == 0 ? OK : -ENOSYS))
# ifdef CONFIG_QSPI_BITORDER
# define QSPI_HWFEAT_MSBFIRST (0 << 0)
# define QSPI_HWFEAT_LSBFIRST (1 << 0)
# endif
# ifdef CONFIG_QSPI_WORD_REVERSE
# define QSPI_HWFEAT_WORD_REVERSE_DISABLE (0 << 1)
# define QSPI_HWFEAT_WORD_REVERSE_ENABLE (1 << 1)
# endif
#else
/* Any attempt to select hardware features with CONFIG_QSPI_HWFEATURES
* deselected will return an -ENOSYS error.
*/
# define QSPI_HWFEATURES(d,f) (((f) == 0) ? OK : -ENOSYS)
#endif
/****************************************************************************
* Name: QSPI_COMMAND
*
* Description:
* Perform one QSPI command transfer
*
* Input Parameters:
* dev - Device-specific state data
* cmdinfo - Describes the command transfer to be performed.
*
* Returned Value:
* Zero (OK) on SUCCESS, a negated errno on value of failure
*
****************************************************************************/
#define QSPI_COMMAND(d,c) (d)->ops->command(d,c)
/* QSPI Command Transfer Flags */
#define QSPICMD_ADDRESS (1 << 0) /* Bit 0: Enable address transfer */
#define QSPICMD_READDATA (1 << 1) /* Bit 1: Enable read data transfer */
#define QSPICMD_WRITEDATA (1 << 2) /* Bit 2: Enable write data transfer */
#define QSPICMD_IDUAL (1 << 3) /* Bit 3: Instruction on two lines */
#define QSPICMD_IQUAD (1 << 4) /* Bit 4: Instruction on four lines */
#define QSPICMD_ISADDRESS(f) (((f) & QSPICMD_ADDRESS) != 0)
#define QSPICMD_ISDATA(f) (((f) & (QSPICMD_READDATA | QSPICMD_WRITEDATA)) != 0)
#define QSPICMD_ISREAD(f) (((f) & QSPICMD_READDATA) != 0)
#define QSPICMD_ISWRITE(f) (((f) & QSPICMD_WRITEDATA) != 0)
#define QSPICMD_ISIDUAL(f) (((f) & QSPICMD_IDUAL) != 0)
#define QSPICMD_ISIQUAD(f) (((f) & QSPICMD_IQUAD) != 0)
/****************************************************************************
* Name: QSPI_MEMORY
*
* Description:
* Perform one QSPI memory transfer
*
* Input Parameters:
* dev - Device-specific state data
* meminfo - Describes the memory transfer to be performed.
*
* Returned Value:
* Zero (OK) on SUCCESS, a negated errno on value of failure
*
****************************************************************************/
#define QSPI_MEMORY(d,m) (d)->ops->memory(d,m)
/* QSPI Memory Transfer Flags */
#define QSPIMEM_READ (0) /* Bit 2: 0=Memory read data transfer */
#define QSPIMEM_WRITE (1 << 2) /* Bit 2: 1=Memory write data transfer */
#define QSPIMEM_DUALIO (1 << 3) /* Bit 3: Use Dual I/O (READ only) */
#define QSPIMEM_QUADIO (1 << 4) /* Bit 4: Use Quad I/O (READ only) */
#define QSPIMEM_SCRAMBLE (1 << 5) /* Bit 5: Scramble data */
#define QSPIMEM_RANDOM (1 << 6) /* Bit 6: Use random key in scrambler */
#define QSPIMEM_IDUAL (1 << 7) /* Bit 7: Instruction on two lines */
#define QSPIMEM_IQUAD (1 << 0) /* Bit 0: Instruction on four lines */
#define QSPIMEM_ISREAD(f) (((f) & QSPIMEM_WRITE) == 0)
#define QSPIMEM_ISWRITE(f) (((f) & QSPIMEM_WRITE) != 0)
#define QSPIMEM_ISDUALIO(f) (((f) & QSPIMEM_DUALIO) != 0)
#define QSPIMEM_ISQUADIO(f) (((f) & QSPIMEM_QUADIO) != 0)
#define QSPIMEM_ISSCRAMBLE(f) (((f) & QSPIMEM_SCRAMBLE) != 0)
#define QSPIMEM_ISIDUAL(f) (((f) & QSPIMEM_IDUAL) != 0)
#define QSPIMEM_ISIQUAD(f) (((f) & QSPIMEM_IQUAD) != 0)
#define QSPIMEM_ISRANDOM(f) \
(((f) & (QSPIMEM_SCRAMBLE|QSPIMEM_RANDOM)) == \
(QSPIMEM_SCRAMBLE|QSPIMEM_RANDOM))
/****************************************************************************
* Name: QSPI_ALLOC
*
* Description:
* Allocate a buffer suitable for DMA data transfer
*
* Input Parameters:
* dev - Device-specific state data
* buflen - Buffer length to allocate in bytes
*
* Returned Value:
* Address of the allocated memory on success; NULL is returned on any
* failure.
*
****************************************************************************/
#define QSPI_ALLOC(d,b) (d)->ops->alloc(d,b)
/****************************************************************************
* Name: QSPI_FREE
*
* Description:
* Free memory returned by QSPI_ALLOC
*
* Input Parameters:
* dev - Device-specific state data
* buffer - Buffer previously allocated via QSPI_ALLOC
*
* Returned Value:
* None.
*
****************************************************************************/
#define QSPI_FREE(d,b) (d)->ops->free(d,b)
/****************************************************************************
* Public Types
****************************************************************************/
/* Certain QSPI devices may required different clocking modes */
enum qspi_mode_e
{
QSPIDEV_MODE0 = 0, /* CPOL=0 CPHA=0 */
QSPIDEV_MODE1, /* CPOL=0 CPHA=1 */
QSPIDEV_MODE2, /* CPOL=1 CPHA=0 */
QSPIDEV_MODE3 /* CPOL=1 CPHA=1 */
};
/* This structure describes one command transfer */
struct qspi_cmdinfo_s
{
uint8_t flags; /* See QSPICMD_* definitions */
uint8_t addrlen; /* Address length in bytes (if QSPICMD_ADDRESS) */
uint16_t cmd; /* Command */
uint16_t buflen; /* Data buffer length in bytes (if QSPICMD_DATA) */
uint32_t addr; /* Address (if QSPICMD_ADDRESS) */
FAR void *buffer; /* Data buffer (if QSPICMD_DATA) */
};
/* This structure describes one memory transfer */
struct qspi_meminfo_s
{
uint8_t flags; /* See QSPMEM_* definitions */
uint8_t addrlen; /* Address length in bytes */
uint8_t dummies; /* Number of dummy read cycles (READ only) */
uint16_t cmd; /* Memory access command */
uint32_t buflen; /* Data buffer length in bytes */
uint32_t addr; /* Memory Address */
uint32_t key; /* Scrambler key */
FAR void *buffer; /* Data buffer */
};
#ifdef CONFIG_QSPI_HWFEATURES
/* This is a type wide enough to support all hardware features */
typedef uint8_t qspi_hwfeatures_t;
#endif
/* The QSPI vtable */
struct qspi_dev_s;
struct qspi_ops_s
{
CODE int (*lock)(FAR struct qspi_dev_s *dev, bool lock);
CODE uint32_t (*setfrequency)(FAR struct qspi_dev_s *dev,
uint32_t frequency);
CODE void (*setmode)(FAR struct qspi_dev_s *dev,
enum qspi_mode_e mode);
CODE void (*setbits)(FAR struct qspi_dev_s *dev, int nbits);
#ifdef CONFIG_QSPI_HWFEATURES
CODE int (*hwfeatures)(FAR struct qspi_dev_s *dev,
qspi_hwfeatures_t features);
#endif
CODE int (*command)(FAR struct qspi_dev_s *dev,
FAR struct qspi_cmdinfo_s *cmdinfo);
CODE int (*memory)(FAR struct qspi_dev_s *dev,
FAR struct qspi_meminfo_s *meminfo);
CODE FAR void *(*alloc)(FAR struct qspi_dev_s *dev, size_t buflen);
CODE void (*free)(FAR struct qspi_dev_s *dev, FAR void *buffer);
};
/* QSPI private data. This structure only defines the initial fields of the
* structure visible to the QSPI client. The specific implementation may
* add additional, device specific fields
*/
struct qspi_dev_s
{
FAR const struct qspi_ops_s *ops;
};
/****************************************************************************
* Public Data
****************************************************************************/
#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
#undef EXTERN
#if defined(__cplusplus)
}
#endif
#endif /* __INCLUDE_NUTTX_SPI_QSPI_H */