/* Copyright (C) 2018 RDA Technologies Limited and/or its affiliates("RDA"). * All rights reserved. * * This software is supplied "AS IS" without any warranties. * RDA assumes no responsibility or liability for the use of the software, * conveys no license or title under any patent, copyright, or mask work * right to the product. RDA reserves the right to make changes in the * software without notification. RDA also make no representation or * warranty that such application will be suitable for the specified use * without further testing or modification. */ #ifndef _DRV_SPI_H_ #define _DRV_SPI_H_ #include #include #include #include "quec_cust_patch.h" #include "quec_proj_config.h" #include "hal_config.h" #ifdef __cplusplus extern "C" { #endif #define CONFIG_GENERAL_SPI_FLASH_MOUNT_POINT "/extn" #define FLASH_START_ADDR 0x00000000 #define FLASH_MOUNT_SIZE (0x00800000 - 0x1000) #define FLASH_EB_SIZE 0x1000 #define FLASH_PB_SIZE 0x200 typedef enum { SPI_I2C_CS0 = 0, SPI_I2C_CS1, SPI_I2C_CS2, SPI_I2C_CS3, #ifdef CONFIG_QUEC_PROJECT_FEATURE_SPI SPI_I2C_GPIO, //使用GPIO的方式来设置GPIO #endif } drvSpiCsSel; typedef enum { SPI_CPOL_LOW = 0, SPI_CPOL_HIGH, } drvSpiCpolPol; typedef enum { SPI_CPHA_1Edge, SPI_CPHA_2Edge, } drvSpiCphaPol; typedef enum { SPI_CS_ACTIVE_HIGH, SPI_CS_ACTIVE_LOW, } drvSpiCsPol; typedef enum { SPI_DI_0 = 0, SPI_DI_1, SPI_DI_2, } drvSpiInputSel; typedef enum { RX_TRIGGER_1_BYTE, RX_TRIGGER_4_BYTE, RX_TRIGGER_8_BYTE, RX_TRIGGER_12_BYTE, } drvSpiRxTrigger; typedef enum { TX_TRIGGER_1_EMPTY, TX_TRIGGER_4_EMPTY, TX_TRIGGER_8_EMPTY, TX_TRIGGER_12_EMPTY, } drvSpiTxTrigger; typedef enum { SPI_CLK_CTRL, SPI_DO_CTRL, SPI_CS0_CTRL, SPI_CS1_CTRL, SPI_CS2_CTRL, } drvSpiPinCtrl; typedef enum { SPI_TRIGGER_1_DATA, SPI_TRIGGER_4_DATA, SPI_TRIGGER_8_DATA, SPI_TRIGGER_12_DATA, } drvSpithreshold; #if defined(CONFIG_SOC_8910) || defined(CONFIG_SOC_8811) typedef struct { uint32_t rxOvf : 1; uint32_t txTh : 1; uint32_t txDmaDone : 1; uint32_t rxTh : 1; uint32_t rxDmaDone : 1; drvSpithreshold Tx_Rthreshold; drvSpithreshold Rx_Tthreshold; } drvSpiIrq; #elif defined(CONFIG_SOC_8850) #ifdef CONFIG_QUEC_PROJECT_FEATURE_SPI //为了兼容8910的定义 typedef struct { uint32_t rxOvf : 1; uint32_t txTh : 1; uint32_t txDmaDone : 1; uint32_t rxTh : 1; uint32_t rxDmaDone : 1; //drvSpithreshold Tx_Rthreshold; //drvSpithreshold Rx_Tthreshold; unsigned int Tx_Rthreshold : 5; //5bit:[0-31]对应0到31档的阈值 unsigned int Rx_Tthreshold : 5; //5bit:[0-31]对应0到31档的阈值 } drvSpiIrq; #else typedef struct { uint32_t rxf_full_raw_sts : 1; // [0] uint32_t rxf_empty_raw_sts : 1; // [1] uint32_t txf_full_raw_sts : 1; // [2] uint32_t tx_fifo_empty_w : 1; // [3] uint32_t rx_ovf_raw_sts : 1; // [4] uint32_t time_out_raw_sts : 1; // [5] uint32_t rxf_full_r : 1; // [6] uint32_t txf_empty_w : 1; // [7] uint32_t tx_end_irq : 1; // [8] uint32_t rx_end_irq : 1; // [9] } drvSpiIrq; #endif #endif typedef enum { SPI_CTRL, INPUT_CTRL, FORCE_0_CTRL, FROCE_1_CTRL, } drvSpiPinState; typedef enum { SPI_DIRECT_POLLING = 0, SPI_DIRECT_IRQ, SPI_DMA_POLLING, SPI_DMA_IRQ, } drvSpiTransferMode; #ifdef CONFIG_SOC_8850 typedef enum { CLK_SOURCE_RTC32, CLK_SOURCE_XTAL26, CLK_SOURCE_RC26_26, CLK_SOURCE_GNSSPLL_133m, CLK_SOURCE_APLL_167, } drvClkSource_t; typedef enum { SPI_WORK_STANDARD, SPI_WORK_SYNC, SPI_WORK_S8, SPI_WORK_3_WIRE, SPI_WORK_SLAVE, } drvSpiWorkMode_t; #endif typedef struct { #ifdef CONFIG_SOC_8811 bool clk_sel; #endif bool inputEn; #ifdef CONFIG_SOC_8850 bool lsb; #endif uint8_t oe_delay; uint32_t name; uint32_t framesize; uint32_t baud; #ifdef CONFIG_SOC_8850 drvSpiWorkMode_t work_mode; drvClkSource_t clk_source; #endif drvSpiCsPol cs_polarity0; drvSpiCsPol cs_polarity1; drvSpiCpolPol cpol; drvSpiCphaPol cpha; drvSpiInputSel input_sel; drvSpiTransferMode transmode; #ifdef CONFIG_SOC_8850 uint8_t rxf_full_thrhld; uint8_t rxf_empty_thrhld; uint8_t txf_full_thrhld; uint8_t txf_empty_thrhld; uint32_t spi_tx_data_len; uint32_t spi_rx_data_len; #endif } drvSpiConfig_t; struct drvSpiMaster; typedef void (*callback)(drvSpiIrq cause); typedef struct drvSpiMaster drvSpiMaster_t; #if !((defined CONFIG_QUEC_PROJECT_FEATURE_SPI4_EXT_NOR_SFFS) || (defined CONFIG_QUEC_PROJECT_FEATURE_BOOT_SPI4_EXTNSFFS)) typedef struct drvGeneralSpiFlash drvGeneralSpiFlash_t; #endif /** * @brief acquire the spi master * * @param cfg : drvSpiConfig_t structure that contains the configuration infomation for specified SPI peripheral * @return * - (NULL) fail * - otherwise the spi master instance */ drvSpiMaster_t *drvSpiMasterAcquire(drvSpiConfig_t cfg); /** * @brief Transmits datas with specific length throuth the SPI peripheral. * * @param d : point to spi instance * @param cs : cs choice of spi * @param sendaddr : point to senddata * for uis8910 since the data will not be spliced, when the frame lenght is greater than 8, the specified data structure must be used * In direct mode : framesize <= 8: sendaddr MUST be of type uint8 framesize > 8 framesize <= 16: sendaddr MUST be of type uint16 framesize > 16: sendaddr MUST be of type uint32 * in DMA mode: framesize <= 8: sendaddr MUST be of type uint8 framesize > 8 : sendaddr MUST be of type uint32 * @param len : data len to be transmitted,len = allbytesize / sizeof(dataformat), eg : uint8[10],len = 10, uint16[10],len = 10. * for uis8811 all data will be processed as 8 bits, and the data will be spliced according the frame lenght,the redundant data will be discarded. * @param len: data len is all bytes. * @return * - (false) fail * - (true) success */ #if defined(CONFIG_SOC_8910) bool drvSpiWrite(drvSpiMaster_t *d, drvSpiCsSel cs, const void *sendaddr, uint32_t len); #elif defined(CONFIG_SOC_8811) bool drvSpiWrite(drvSpiMaster_t *d, drvSpiCsSel cs, void *sendaddr, uint32_t len); #elif defined(CONFIG_SOC_8850) uint32_t drvSpiWrite(drvSpiMaster_t *d, const void *sendaddr, uint32_t len); #else uint32_t drvSpiWrite(drvSpiMaster_t *d, void *sendaddr, uint32_t len); #endif #if defined(CONFIG_SOC_8850) /** * @brief config spi cs * @param d : point to spi instance * csnum: cs number * cschoose: cs status * @return : * -true * -false */ bool drvSpiCsConfig(drvSpiMaster_t *d, drvSpiCsSel csnum, bool cschoose); /** * @brief config spi regs * @param d : point to spi instance * @return : None */ void drvSpiRegsConfig(drvSpiMaster_t *d); #endif /** * @brief Receive the most recent received datas by the SPI peripheral. * * @param d : point to spi instance * @param cs : cs choice of spi * @param sendaddr : point to senddata address.in this case, you can specify the content of datas. * @param readaddr : point to readaddr address. * for uis8910 since the data will not be spliced, when the frame lenght is greater than 8, the specified data structure must be used * In direct mode : framesize <= 8: sendaddr MUST be of type uint8 framesize > 8 framesize <= 16: sendaddr MUST be of type uint16 framesize > 16: sendaddr MUST be of type uint32 * in DMA mode: framesize <= 8: sendaddr MUST be of type uint8 framesize > 8 : sendaddr MUST be of type uint32 * @param len : data len to be transmitted,len = allbytesize / sizeof(dataformat), eg : uint8[10],len = 10, uint16[10],len = 10. * for uis8811 all data will be processed as 8 bits, and the data will be spliced according the frame lenght,the redundant data will be discarded. * @param len: data len is all bytes. * @return * - (false) fail * - (true) success */ #ifndef CONFIG_SOC_8850 bool drvSpiRead(drvSpiMaster_t *d, drvSpiCsSel cs, void *sendaddr, void *readaddr, uint32_t len); #else uint32_t drvSpiRead(drvSpiMaster_t *d, void *readaddr, uint32_t len); uint32_t drvSpiReadWrite(drvSpiMaster_t *d, void *sendaddr, void *readaddr, uint32_t len); uint32_t drvSpiRWDirectPolling(drvSpiMaster_t *d, void *sendaddr, void *readaddr, uint32_t len); uint32_t drvSpiRWDmaPolling(drvSpiMaster_t *d, void *sendaddr, void *readaddr, uint32_t len); #endif #ifndef CONFIG_SOC_8850 /** * @brief get irq mask of the SPI peripheral * @param d : point to spi instance * @return : None */ void prvSpiGetIrqMask(drvSpiMaster_t *d); #endif /** * @brief config irq of the SPI peripheral * @param d : point to spi instance * @param mask : point to the irq mask cofig * @param callfunc :call back function . * @return : None */ void drvSpiSetIrqHandle(drvSpiMaster_t *d, callback callfunc); /** * @brief config irq of the SPI peripheral * @param d : point to spi instance * @param mask : point to the irq mask cofig * @param callfunc :call back function . * @return : None */ void drvSpiSetIrqMask(drvSpiMaster_t *d, drvSpiIrq *mask); /** * @brief clear irq of the SPI peripheral * @param d : point to spi instance * @return : None */ void drvSpiClrIrqMask(drvSpiMaster_t *d); /** * @brief Enable the Tx stream mode,Used for SD/MMC SPI mode. * @param d : point to spi instance * @param stream_bit : value of stream mode * @param on : enable or disable stream mode * - true enable stream mode, this mode provide infinite bit stream for sending after fifo is empty, all generated data have the same value, the vaule is in stream bit) - false disable stream mode * @return : None */ void drvSpiEnableStreamMode(drvSpiMaster_t *d, uint8_t stream_bit, bool on); /** * @brief get the Number of data in spi rx FIFO * @param d : point to spi instance * @return : Number of data in spi rx FIFO */ uint8_t drvSpiGetRxLevel(drvSpiMaster_t *d); /** * @brief get the Number of empty spot in spi tx FIFO * @param d : point to spi instance * @return : Number of empty spot in spi tx FIFO */ uint8_t drvSpiGetTxFree(drvSpiMaster_t *d); /** * @brief config pin state of the spi peripheral * @param d : point to spi instance * @param pinctrl : where it can be * - SPI_CLK_CTRL SPI_DO_CTRL SPI_CS0_CTRL SPI_CS1_CTRL SPI_CS2_CTRL * @param pinstate : pin can be config as : * - SPI_CTRL (ctrl by spi peripheral automaticly) * - INPUT_CTRL (ctrl pin in input mode) * - FORCE_0_CTRL (froced pull down) * - FROCE_1_CTRL (froced pull up) * @return : None */ #ifndef CONFIG_SOC_8850 void drvSpiPinControl(drvSpiMaster_t *d, drvSpiPinCtrl pinctrl, drvSpiPinState pinstate); #else #ifdef CONFIG_QUEC_PROJECT_FEATURE bool drvSpiCsConfig(drvSpiMaster_t *d, drvSpiCsSel csnum, bool cschoose); #endif #endif /** * @brief release the spi peripheral * @param d : point to spi instance * @return : None */ void drvSpiMasterRelease(drvSpiMaster_t *d); #if !((defined CONFIG_QUEC_PROJECT_FEATURE_SPI4_EXT_NOR_SFFS) || (defined CONFIG_QUEC_PROJECT_FEATURE_BOOT_SPI4_EXTNSFFS)) /** * @brief open spi flash device * * @param name: DRV_NAME_SPI1, spi device name * @return * - (NULL) fail * - otherwise the spi flash instance */ drvGeneralSpiFlash_t *drvGeneralSpiFlashOpen(uint32_t name); /** * @brief config iomux of spi port, config SPI, read spi flash ID * * @param name: DRV_NAME_SPI1, spi device name * @return * - none */ void drvGeneralSpiFlashInit(uint32_t name); /** * @brief spi write enable * * @param null * @return * - none */ void drvGeneralSpiFlashEnable(void); /** * @brief wait for spi flash to complete the last operation * * @param null * @return * - false: time out * - true: normal */ int drvGeneralSpiFlashFininsh(void); /** * @brief spi flash read * * @param offset : absolute read address of spi flash * size : read size * pbuf : read buffer address * @return * - true */ int drvGeneralSpiFlashRead(uint32_t offset, uint32_t size, void *pbuf); /** * @brief spi flash write * * @param d : drvGeneralSpiFlash_t strunture of spi flash device * offset : absolute write address of spi flash * data : write data buffer address * size : write size * @return * - false: fail * - true: success */ bool drvGeneralSpiFlashWrite(drvGeneralSpiFlash_t *d, uint32_t offset, const void *data, size_t size); /** * @brief spi flash erase * * @param d : drvGeneralSpiFlash_t strunture of spi flash device * offset : absolute erase address of spi flash * size : erase size * @return * - false: fail * - true: success */ bool drvGeneralSpiFlashErase(drvGeneralSpiFlash_t *d, uint32_t offset, size_t size); /** * @brief spi flash write enable test * * @param null * @return * - none */ bool drvGeneralSpiFlashWriteEnableTest(void); /** * @brief spi flash write test * * @param offset : absolute write address of spi flash * size : write size * buf : write buffer address * @return * - false: fail * - true: success */ int drvGeneralSpiFlashWriteTest(uint32_t offset, uint32_t size, const void *buf); /** * @brief spi flash erase test * * @param offset : absolute erase address of spi flash * size : erase size * @return * - false: fail * - true: success */ int drvGeneralSpiFlashEraseTest(uint32_t offset, uint32_t size); #endif #ifdef __cplusplus } #endif #endif