366 lines
12 KiB
C
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 */
|