Files
kunlun/export/inc/bsp/iot_spi_api.h
2024-09-28 14:24:04 +08:00

402 lines
11 KiB
C

/****************************************************************************
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
be copied by any method or incorporated into another program without
the express written consent of Aerospace C.Power. This Information or any portion
thereof remains the property of Aerospace C.Power. The Information contained herein
is believed to be accurate and Aerospace C.Power assumes no responsibility or
liability for its use in any way and conveys no license or title under
any patent or copyright and makes no representation or warranty that this
Information is free from patent or copyright infringement.
****************************************************************************/
#ifndef IOT_SPI_API_H
#define IOT_SPI_API_H
#ifdef __cplusplus
extern "C" {
#endif
/** \defgroup SPI_APIs SPI APIs
* @brief SPI APIs
*
*
*
*/
/** @addtogroup SPI_APIs
* @{
*/
#define INCLUDE_DW_APB_SSI
#ifdef INCLUDE_DW_APB_SSI
/**
* @brief Poll mode Usage:
xfer_buf spi_tx, spi_rx;
iot_spi_cfg_t cfg = {0};
cfg.gpio.clk = xx;
cfg.gpio.cs = xx;
cfg.gpio.miso = xx;
cfg.gpio.mosi = xx;
cfg.port = xx; //see spi_device_list
iot_spi_module_init(&cfg);
iot_spi_dev_register(DEVICE_SPI0_MASTER, 1, 0, \
isr_func, INT_RXFIFO_FULL|INT_TXFIFO_EMPTY);
spi_tx.p_nt = &spi_rx; // Next buffer after this sent.
spi_tx.txbuf = spi_tx_buf;
spi_tx.rxbuf = NULL; // dummy data will be dropped.
spi_tx.size = SPI_SENT_SIZE; //To send SPI_SENT_SIZE byte from spi_tx_buf.
spi_rx.xfer_size =0;
spi_rx.p_nt = NULL;
spi_rx.rxbuf = spi_rx_buf;
spi_rx.txbuf = tmp_buf; // dummy data will be sent to slaver.
spi_rx.size = SPI_READ_SIZE; // To get SPI_READ_SIZE size of data.
spi_rx.xfer_size =0;
iot_spi_poll_transfer(DEVICE_SPI0_MASTER, &spi_tx);
...
*/
/**
* @brief SPI timing.
*/
struct timing_config
{
int scpol:1; /**< CLK stay in Low (0) or high (1) when idle */
int scph:1; /**< 0 - Data transmited on falling edge of CS,
captured on the 1ST edge of CLK
1 - Data transmited on the 1ST edge of CLK,
captured on the 2ND edge of CLK. */
int scph_tgl:1;
int sste:1; /**< scph_tgl=0 & sste=1 , CS toggled between frames and
CLK set default between frames .Else, CS stays LOW and CLK run
continuously alwaays */
int rev:28;
};
/**
* @brief SPI dma config.
*/
struct spi_dma_config
{
short rx_enable; /**< If to enable rx-DMA */
short tx_enable; /**< If to enable tx-DMA */
int rx_datalevel; /**< This bit field controls the level at which
a DMA request is made by the receive logic.The watermark level
= rx_datalevel+1 */
int tx_datalevel; /**< This bit field controls the level at which
a DMA request is made by the transmit logic.It is equal to the
watermark level */
};
/**
* @brief SPI device list.
*/
enum spi_device_list
{
DEVICE_SPI0_MASTER,
DEVICE_SPI1_MASTER,
DEVICE_SPI0_SLAVER,
DEVICE_SPI2_MASTER,
DEVICE_SPI_MAX
};
typedef struct _iot_spi_gpio_sel {
uint8_t clk;
uint8_t cs;
uint8_t miso;
uint8_t mosi;
} iot_spi_gpio_sel_t;
typedef struct _iot_spi_cfg {
uint8_t port;
iot_spi_gpio_sel_t gpio;
} iot_spi_cfg_t;
#define SPI_DFRAME_SIZE_8 8
#define SPI_DFRAME_SIZE_16 16
#define SPI_DFRAME_SIZE_32 32 /* NOT available for NOW */
#define DEVICE_SPI_CNT DEVICE_SPI_MAX
#define DEVICE_SPI_SYS_CLK 75*1000*1000 /* 75M */
#define DEVICE_SPI_DEFAULT_FREQUENCY 100*1000 /* 100K */
#define DEVICE_SPI_DEFAULT_RX_THRESHOULD 12
#define DEVICE_SPI_DEFAULT_TX_THRESHOULD 5
#define DEVICE_SPI_DEFAULT_CS_EN 1
/* Mask */
#define INT_RXFIFO_FULL BIT(4)
#define INT_RXFIFO_OVERFLOW BIT(3)
#define INT_RXFIFO_UNDERFLOW BIT(2)
#define INT_TXFIFO_EMPTY BIT(1)
#define INT_TXFIFO_OVERFLOW BIT(0)
#else
#error "No SPI device included !"
#endif
#define SPI_MASTER 0
#define SPI_SLAVER 1
/**
* We provide a new iot_spi_dev_open function to replace iot_spi_module_init.
* The macro definition here is for compatibility with previous programs.
*/
#define iot_spi_module_init(cfg) iot_spi_dev_open(cfg)
typedef void (*int_isr)(int);
typedef void (*dma_complete_cb_t)(int);
/**
* @brief SPI transerver mode.
*/
enum trans_mode
{
TMOD_TRANCIEVER = 0, /**< transmit and receive */
TMOD_TRANSMITER = 1, /**< transmit only */
TMOD_RECIEVER = 2, /**< receive only */
};
/**
* @brief SPI frame mode.
*/
enum frame_format
{
FRM_STD, /**< Only mode supported. */
FRM_DUAL,
FRM_QUAD,
FRM_OCTAL
};
/**
* @brief SPI config.
*/
typedef struct spi_config
{
/** Master or slaver */
int dev_type:2;
/** trans_mode */
int trs_mode:2;
/** frame_format */
int frm_fmt:2;
/** Data frame size, SPI_DFRAME_SIZE_8 suggested. */
int dfrm_sz:6;
/** slave select enable*/
int cs_en:1;
int rev:19;
/** Device frequency. Like DEVICE_SPI_DEFAULT_FREQUENCY */
int frq;
/**< Threshold for reviecing fifo. 0xF is max */
int rx_thd;
/**< Threshold for transmitting fifo. 0xF is max */
int tx_thd;
}spi_cfg;
/**
* @brief SPI xfer buffer.
*/
typedef struct spi_xfer_buf
{
struct spi_xfer_buf *p_nt;
/** bytes for recieving or for transmiting. */
int size;
/** bytes recieved or transmited */
int xfer_size;
char *rxbuf;
char *txbuf;
}xfer_buf;
typedef struct timing_config tm_cfg;
typedef struct spi_dma_config sdma_cfg;
/**
* @brief iot_spi_dev_register_detail() - Register a spi device.For detail using.
* @param dev: See enum spi_device_list.
* @param cfg: See spi_cfg, For spi config.
* @param tm: See struct timing_config, For timming config.
* @param dma_cfg: See sdma_cfg, For spi dma.
* @param isr: See int_isr, ISR for interrupts.
* @param int_mask: Interrupt mask. See #define INT_*.
* @see ERR_FAIL
* @see ERR_OK
* @return ERR_FAIL -- Operation failed.
* @return ERR_OK -- Operation Successful.
*/
int iot_spi_dev_register_detail
(int dev, spi_cfg * cfg, tm_cfg *tm,
sdma_cfg* dma_cfg, int_isr isr, int int_mask);
/**
* @brief iot_spi_dev_register_detail_dma() - Register a spi device in dma.
* @param dev: See enum spi_device_list.
* @param cfg: See spi_cfg, For spi config.
* @param tm: See struct timing_config, For timming config.
* @param dma_cfg: See sdma_cfg, For spi dma.
* @param isr: See int_isr, ISR for interrupts.
* @param int_mask: Interrupt mask. See #define INT_*.
* @param cb: Dma tansfer complete will call it
* @see ERR_FAIL
* @see ERR_OK
* @return ERR_FAIL -- Operation failed.
* @return ERR_OK -- Operation Successful.
*/
int iot_spi_dev_register_detail_dma(int dev, spi_cfg * cfg, tm_cfg *tm,
sdma_cfg* dma_cfg, dma_complete_cb_t cb);
/**
* @brief iot_spi_dev_register() - Register a spi device.
* @param dev: See enum spi_device_list.
* @param is_master: 0 for slaver, else master.
* @param is_dma: 0 for none-dma, else dma..
* @param isr: See int_isr, ISR for interrupts.
* @param int_mask: Interrupt mask. See #define INT_*.
* @param auto_cs: true - cs signal controled by hardware,
* false - cs signal controled by software. In this mode, cs signal
* also controled by iot_spi_poll_transfer() automatically.
* @see ERR_FAIL
* @see ERR_OK
* @return ERR_FAIL -- Operation failed.
* @return ERR_OK -- Operation Successful.
*/
int iot_spi_dev_register
(int dev, int is_master, int is_dma, int_isr isr, int int_mask, int auto_cs);
/**
* @brief iot_spi_clear_int_status() - Clear status of interrupts.
* @param dev: See enum spi_device_list.
* @see ERR_FAIL
* @see ERR_OK
* @return ERR_FAIL -- Operation failed.
* @return ERR_OK -- Operation Successful.
*/
int iot_spi_clear_int_status(int dev);
/**
* @brief iot_spi_set_int_enable() - Enable interrupts.
* @param dev: See enum spi_device_list.
* @param ena_msk: Interrupt mask. See #define INT_*.
* @see ERR_FAIL
* @see ERR_OK
* @return ERR_FAIL -- Operation failed.
* @return ERR_OK -- Operation Successful.
*/
int iot_spi_set_int_enable(int dev, int ena_msk);
/**
* @brief iot_spi_set_int_enable() - Disable interrupts.
* @param dev: See enum spi_device_list.
* @param dis_msk: Interrupt mask. See #define INT_*.
* @see ERR_FAIL
* @see ERR_OK
* @return ERR_FAIL -- Operation failed.
* @return ERR_OK -- Operation Successful.
*/
int iot_spi_set_int_disable(int dev, int dis_msk);
/**
* @brief iot_spi_get_rx_data_cnt() - Get recieved data counting..
* @param dev: See enum spi_device_list.
* @param *cnt: Pointer to return the counting.
* @see ERR_FAIL
* @see ERR_OK
* @return ERR_FAIL -- Operation failed.
* @return ERR_OK -- Operation Successful.
*/
int iot_spi_get_rx_data_cnt(int dev, int * cnt);
/**
* @brief iot_spi_get_tx_data_space_cnt() - Get data counting we can
still put into fifo.
* @param dev: See enum spi_device_list.
* @param *cnt: Pointer to return the counting.
* @see ERR_FAIL
* @see ERR_OK
* @return ERR_FAIL -- Operation failed.
* @return ERR_OK -- Operation Successful.
*/
int iot_spi_get_tx_data_space_cnt(int dev, int * cnt);
/**
* @brief iot_spi_read_data() - Get the data recieved.
* @param dev: See enum spi_device_list.
* @param *buf: Buffer to store the data.
* @param *rd_size: Size of data that wanna got.
* @return -- Size of data that got finally..
*/
int iot_spi_read_data(int dev, char *buf, int rd_size);
/**
* @brief iot_spi_write_data() - Transmit data.
* @param dev: See enum spi_device_list.
* @param *buf: Buffer to store the data.
* @param *wt_size: Size of data that wanna sent.
* @return -- Size of data that sent finally..
*/
int iot_spi_write_data(int dev, char *buf, int wt_size);
/**
* @brief iot_spi_poll_transfer() - Transceive data.
* @param dev: See enum spi_device_list.
* @param *buf: Buffer to tramsmit and recieve.
* @return ERR_FAIL -- Operation failed.
* @return ERR_OK -- Operation Successful.
*/
int iot_spi_poll_transfer(int dev, xfer_buf *buf);
/**
* @brief iot_spi_poll_transfer_by_dma() - Transceive data by dma.
* @param dev: See enum spi_device_list.
* @param *buf: Buffer to tramsmit and recieve, support single xfer_buf only
* @param flag: dma complete will set flag to 1
* @return ERR_FAIL -- Operation failed.
* @return ERR_OK -- Operation Successful.
*/
int iot_spi_poll_transfer_by_dma(int dev, xfer_buf *buf);
/**
* @brief iot_spi_dev_open() - open and initialize the specified SPI port .
* @param cfg: the pointer to spi initial config structure,
* cfg->port(see spi_device_list), cfg->gpio.clk, cfg->gpio.mosi,
* cfg->gpio.miso must be specified.
* @return ERR_FAIL -- Operation failed.
* @return ERR_OK -- Operation Successful.
*/
int iot_spi_dev_open(iot_spi_cfg_t *cfg);
/**
* @brief iot_spi_tx_fifo_empty_status() - check the tx fifo is empty or not.
* @return 0 -- tx fifo is NOT empty.
* @return 1 -- tx fifo is empty.
*/
int iot_spi_tx_fifo_empty_status(int dev);
/**
* @brief iot_spi_check_dev_invalidity() - check dev is invalid.
* @return 0 -- dev is valid
* @return 1 -- dev is invalid.
*/
int iot_spi_check_dev_invalidity(int dev);
/**
* @}
*/
#define DEVICE_SPI_PORT_INVALID(d) (iot_spi_check_dev_invalidity(d))
#ifdef __cplusplus
}
#endif
#endif