| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620 |
- /*
- * Copyright : (C) 2022 Phytium Information Technology, Inc.
- * All Rights Reserved.
- *
- * This program is OPEN SOURCE software: you can redistribute it and/or modify it
- * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd,
- * either version 1.0 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the Phytium Public License for more details.
- *
- *
- * FilePath: fspim.c
- * Date: 2022-02-10 14:53:42
- * LastEditTime: 2022-02-18 09:08:32
- * Description: This files is for spim api implementation
- *
- * Modify History:
- * Ver Who Date Changes
- * ----- ------ -------- --------------------------------------
- * 1.0 zhugengyu 2021-12-3 init commit
- * 1.1 zhugengyu 2022-4-15 support test mode
- * 1.2 zhugengyu 2022-5-13 support spi dma
- */
- /***************************** Include Files *********************************/
- #include <string.h>
- #include "fio.h"
- #include "ferror_code.h"
- #include "ftypes.h"
- #include "fdebug.h"
- #include "fspim_hw.h"
- #include "fspim.h"
- /************************** Constant Definitions *****************************/
- /**************************** Type Definitions *******************************/
- /***************** Macros (Inline Functions) Definitions *********************/
- #define FSPIM_DEBUG_TAG "SPIM"
- #define FSPIM_ERROR(format, ...) FT_DEBUG_PRINT_E(FSPIM_DEBUG_TAG, format, ##__VA_ARGS__)
- #define FSPIM_WARN(format, ...) FT_DEBUG_PRINT_W(FSPIM_DEBUG_TAG, format, ##__VA_ARGS__)
- #define FSPIM_INFO(format, ...) FT_DEBUG_PRINT_I(FSPIM_DEBUG_TAG, format, ##__VA_ARGS__)
- #define FSPIM_DEBUG(format, ...) FT_DEBUG_PRINT_D(FSPIM_DEBUG_TAG, format, ##__VA_ARGS__)
- /************************** Function Prototypes ******************************/
- FError FSpimReset(FSpim *instance_p);
- /************************** Variable Definitions *****************************/
- static const char *FSPIM_ERROR_CODE_MSG[FSPIM_NUM_OF_ERR_CODE] =
- {
- "FSPIM_SUCCESS : fspim success",
- "FSPIM_ERR_INVAL_STATE : fspim invalid state",
- "FSPIM_ERR_NOT_READY : fspim driver not ready",
- "FSPIM_ERR_INVAL_PARAM : fspim invalid input parameters",
- "FSPIM_ERR_BUS_BUSY : fspim bus is busy",
- "FSPIM_ERR_NOT_SUPPORT : fspim not support operation",
- "FSPIM_ERR_TIMEOUT : fspim wait timeout",
- "FSPIM_ERR_TRANS_FAIL : fspim data transfer failed",
- };
- /*****************************************************************************/
- /* 此文件主要为了完成用户对外接口,用户可以使用这些接口直接开始工作 */
- /* - 包括用户API的定义和实现
- - 同时包含必要的OPTION方法,方便用户进行配置
- - 如果驱动可以直接进行I/O操作,在此源文件下可以将API 进行实现 */
- /*
- * @name: FSpimCfgInitialize
- * @msg: Initializes a specific instance such that it is ready to be used.
- * @param {FSpim} *instance_p FSPIM驱动控制数据
- * @param {FSpimConfig} *config_p FSPIM驱动配置数据
- * @return 驱动初始化的错误码信息,FSPIM_SUCCESS 表示初始化成功,其它返回值表示初始化失败
- */
- FError FSpimCfgInitialize(FSpim *instance_p, const FSpimConfig *input_config_p)
- {
- FASSERT(instance_p && input_config_p);
- uintptr base_addr = instance_p->config.base_addr;
- FError ret = FSPIM_SUCCESS;
- /*
- * If the device is started, disallow the initialize and return a Status
- * indicating it is started. This allows the user to de-initialize the device
- * and reinitialize, but prevents a user from inadvertently
- * initializing.
- */
- if (FT_COMPONENT_IS_READY == instance_p->is_ready)
- {
- FSPIM_WARN("device is already initialized!!!");
- }
- /*
- * Set default values and configuration data, including setting the
- * callback handlers to stubs so the system will not crash should the
- * application not assign its own callbacks.
- */
- FSpimDeInitialize(instance_p);
- instance_p->config = *input_config_p;
- /*
- * Reset the device.
- */
- ret = FSpimReset(instance_p);
- if (FSPIM_SUCCESS == ret)
- {
- instance_p->is_ready = FT_COMPONENT_IS_READY;
- }
- return ret;
- }
- /**
- * @name: FSpimDeInitialize
- * @msg: DeInitialization function for the device instance
- * @return {无}
- * @param {FSpim} *instance_p FSPIM驱动控制数据
- */
- void FSpimDeInitialize(FSpim *instance_p)
- {
- FASSERT(instance_p);
- instance_p->is_ready = 0;
- memset(instance_p, 0, sizeof(*instance_p));
- return;
- }
- /**
- * @name: FSpimReset
- * @msg: 重置FSPIM控制器
- * @return {FError} FSPIM_SUCCESS表示重置成功,其它返回值表示重置失败
- * @param {FSpim} *instance_p
- */
- FError FSpimReset(FSpim *instance_p)
- {
- FASSERT(instance_p);
- uintptr base_addr = instance_p->config.base_addr;
- FError ret = FSPIM_SUCCESS;
- u32 reg_val;
- u32 fifo;
- /* 禁用SPI控制器 */
- FSpimSetEnable(base_addr, FALSE);
- /* 选择数据长度和帧格式 */
- reg_val = FSPIM_CTRL_R0_DFS(FSPIM_DEFAULT_DFS) |
- FSPIM_CTRL_R0_FRF(FSPIM_DEFAULT_FRF) |
- FSPIM_CTRL_R0_CFS(FSPIM_DEFAULT_CFS);
- if (instance_p->config.en_test)
- {
- reg_val |= FSPIM_CTRL_R0_SLV_SRL(FSPIM_SRL_TEST); /* 设置测试模式,TX Fifo和RX Fifo内部短接 */
- }
- else
- {
- reg_val |= FSPIM_CTRL_R0_SLV_SRL(FSPIM_SRL_NORAML); /* 设置为正常模式 */
- }
- FSpimSetCtrlR0(base_addr, reg_val);
- /* 选择串行时钟极性和相位 */
- FSpimSetCpha(base_addr, instance_p->config.cpha);
- FSpimSetCpol(base_addr, instance_p->config.cpol);
- /* 设置传输模式 */
- FSpimSetTransMode(base_addr, FSPIM_TRANS_MODE_RX_TX);
- /* 禁用slave */
- FSpimSetSlaveEnable(base_addr, FALSE);
- /* 禁用SPI 中断,设置slave设备 */
- FSpimMaskIrq(base_addr, FSPIM_IMR_ALL_BITS);
- FSpimSelSlaveDev(base_addr, instance_p->config.slave_dev_id);
- /* 获取SPI RX/TX FIFO 深度 */
- if (0 == instance_p->tx_fifo_len)
- {
- fifo = FSpimGetTxFifoDepth(base_addr);
- instance_p->tx_fifo_len = ((fifo == 1) ? 0 : fifo);
- FSPIM_INFO("fifo depth %d tx_fifo_len %d", fifo, instance_p->tx_fifo_len);
- }
- if (0 == instance_p->rx_fifo_len)
- {
- fifo = FSpimGetRxFifoDepth(base_addr);
- instance_p->rx_fifo_len = ((fifo == 1) ? 0 : fifo);
- FSPIM_INFO("fifo depth %d tx_fifo_len %d", fifo, instance_p->tx_fifo_len);
- }
- FSPIM_WRITE_REG32(base_addr, FSPIM_DMA_CR_OFFSET, 0x0); /* disable ddma */
- if (instance_p->config.en_dma)
- {
- /* recv data in continuous way */
- FSpimSetCtrlR1(base_addr, FSPIM_CTRL_R1_NDF_64KB);
- /* setup fifo threshold */
- FSpimSetRxFifoThreshold(base_addr, instance_p->rx_fifo_len);
- FSpimSetTxFifoThreshold(base_addr, instance_p->tx_fifo_len);
- /* setup fifo DMA level to trigger interrupt */
- FSpimSetRxDMALevel(base_addr, FSPIM_RX_DMA_LEVEL);
- FSpimSetTxDMALevel(base_addr, FSPIM_TX_DMA_LEVEL);
- }
- else
- {
- FSpimSetCtrlR1(base_addr, 0);
- FSpimSetRxFifoThreshold(base_addr, 0);
- FSpimSetTxFifoThreshold(base_addr, 0);
- FSpimSetRxDMALevel(base_addr, 0);
- FSpimSetTxDMALevel(base_addr, 0);
- }
- ret = FSpimSetSpeed(base_addr, instance_p->config.max_freq_hz);
- if (FSPIM_SUCCESS != ret)
- return ret;
- FSPIM_WRITE_REG32(base_addr, FSPIM_RX_SAMPLE_DLY_OFFSET, FSPIM_DEFAULT_RSD);
- /* 使能SPI控制器 */
- FSpimSetEnable(base_addr, TRUE);
- return ret;
- }
- /**
- * @name: FSpimGetTxRound
- * @msg: 计算当前FIFO支持的发送字节数
- * @return {fsize_t} 当前TX FIFO可以容纳的字节数
- * @param {FSpim} *instance_p
- */
- static fsize_t FSpimGetTxRound(FSpim *instance_p)
- {
- fsize_t data_width = instance_p->config.n_bytes;
- uintptr base_addr = instance_p->config.base_addr;
- fsize_t tx_left_round, tx_fifo_room, rx_tx_gap;
- tx_left_round = (fsize_t)(instance_p->tx_buff_end - instance_p->tx_buff) / data_width;
- tx_fifo_room = instance_p->tx_fifo_len -
- FSpimGetTxFifoLevel(base_addr);
- rx_tx_gap = ((fsize_t)(instance_p->rx_buff_end - instance_p->rx_buff) -
- (fsize_t)(instance_p->tx_buff_end - instance_p->tx_buff)) / data_width;
- FSPIM_DEBUG("tx_left_round: %d, tx_fifo_room: %d, gap: %d",
- tx_left_round,
- tx_fifo_room,
- ((fsize_t)(instance_p->tx_fifo_len) - rx_tx_gap));
- return min3(tx_left_round,
- tx_fifo_room,
- ((fsize_t)(instance_p->tx_fifo_len) - rx_tx_gap));
- }
- /**
- * @name: FSpimFifoTx
- * @msg: 利用Fifo进行发送
- * @return {无}
- * @param {FSpim} *instance_p
- */
- void FSpimFifoTx(FSpim *instance_p)
- {
- FASSERT(instance_p);
- fsize_t tx_round = FSpimGetTxRound(instance_p);
- FSPIM_DEBUG("tx round: %d", tx_round);
- uintptr base_addr = instance_p->config.base_addr;
- u32 data_width = instance_p->config.n_bytes;
- u16 data = 0xff;
- while (tx_round)
- {
- if (instance_p->tx_buff_end - instance_p->length)
- {
- if (FSPIM_1_BYTE == data_width)
- {
- /*
- * Data Transfer Width is Byte (8 bit).
- */
- data = *(u8 *)(instance_p->tx_buff);
- }
- else if (FSPIM_2_BYTE == data_width)
- {
- /*
- * Data Transfer Width is Half Word (16 bit).
- */
- data = *(u16 *)(instance_p->tx_buff);
- }
- else
- {
- FASSERT(0);
- }
- }
- FSpimWriteData(base_addr, data);
- FSPIM_DEBUG(" send 0x%x", data);
- instance_p->tx_buff += data_width;
- tx_round--;
- }
- }
- /**
- * @name: FSpimGetRxRound
- * @msg: 获取当前Fifo支持的接收字节数
- * @return {fsize_t} 当前RX FIFO可以容纳的字节数
- * @param {FSpim} *instance_p
- */
- static fsize_t FSpimGetRxRound(FSpim *instance_p)
- {
- fsize_t data_width = instance_p->config.n_bytes;
- uintptr base_addr = instance_p->config.base_addr;
- fsize_t rx_left_round = (fsize_t)(instance_p->rx_buff_end - instance_p->rx_buff) / data_width;
- FSPIM_DEBUG("left round %d, rx level %d", rx_left_round, FSpimGetRxFifoLevel(base_addr));
- return min(rx_left_round, (fsize_t)FSpimGetRxFifoLevel(base_addr));
- }
- /**
- * @name: FSpimFifoRx
- * @msg: 利用Fifo进行接收
- * @return {无}
- * @param {FSpim} *instance_p
- */
- void FSpimFifoRx(FSpim *instance_p)
- {
- FASSERT(instance_p);
- fsize_t rx_round = FSpimGetRxRound(instance_p);
- FSPIM_DEBUG("rx round: %d", rx_round);
- uintptr base_addr = instance_p->config.base_addr;
- u32 data_width = instance_p->config.n_bytes;
- u16 data;
- while (rx_round)
- {
- data = FSpimReadData(base_addr);
- if ((fsize_t)(instance_p->rx_buff_end - instance_p->length))
- {
- if (FSPIM_1_BYTE == data_width)
- {
- /*
- * Data Transfer Width is Byte (8 bit).
- */
- *(u8 *)(instance_p->rx_buff) = (u8)data;
- FSPIM_DEBUG(" recv 0x%x", *(u8 *)(instance_p->rx_buff));
- }
- else if (FSPIM_2_BYTE == data_width)
- {
- /*
- * Data Transfer Width is Half Word (16 bit).
- */
- *(u16 *)(instance_p->rx_buff) = (u16)data;
- FSPIM_DEBUG(" recv 0x%x", *(u16 *)(instance_p->rx_buff));
- }
- else
- {
- FASSERT(0);
- }
- }
- instance_p->rx_buff += data_width;
- rx_round--;
- }
- return;
- }
- /**
- * @name: FSpimTransferPollFifo
- * @msg: 先发送后接收数据 (阻塞处理),利用Fifo进行处理
- * @return {FError} FSPIM_SUCCESS表示处理成功,其它返回值表示处理失败
- * @param {FSpim} *instance_p 驱动控制数据
- * @param {void} *tx_buf 写缓冲区,可以为空,为空时表示只关注读数据,此时驱动会发送0xff读数据
- * @param {void} *rx_buf 读缓冲区, 可以为空,为空时表示值关注写数据,此时SPI总线上返回的数据会被抛弃
- * @param {fsize_t} len 进行传输的长度,如果tx_buf或者rx_buf不为空,则两个buf的长度必须为len
- - 使用此函数前需要确保FSPIM驱动初始化成功
- - 从函数不会使用中断,会按照TX FIFO的深度进行传输,每次发送填满TX FIFO后触发发送/接收动作
- */
- FError FSpimTransferPollFifo(FSpim *instance_p, const void *tx_buf, void *rx_buf, fsize_t len)
- {
- FASSERT(instance_p);
- u32 reg_val;
- uintptr base_addr = instance_p->config.base_addr;
- u32 data_width = instance_p->config.n_bytes;
- u32 tx_level;
- FError ret = FSPIM_SUCCESS;
- if (FT_COMPONENT_IS_READY != instance_p->is_ready)
- {
- FSPIM_ERROR("device is already initialized!!!");
- return FSPIM_ERR_NOT_READY;
- }
- FSpimSetEnable(base_addr, FALSE);
- reg_val = FSpimGetCtrlR0(base_addr);
- reg_val &= ~FSPIM_CTRL_R0_DFS_MASK;
- reg_val |= FSPIM_CTRL_R0_DFS((data_width << 3) - 1);
- reg_val &= ~FSPIM_CTRL_R0_TMOD_MASK;
- if (tx_buf && rx_buf)
- reg_val |= FSPIM_CTRL_R0_TMOD(FSPIM_TMOD_RX_TX);
- else if (rx_buf)
- reg_val |= FSPIM_CTRL_R0_TMOD(FSPIM_TMOD_RX_ONLY);
- else
- reg_val |= FSPIM_CTRL_R0_TMOD(FSPIM_TMOD_RX_TX);
- FSpimSetCtrlR0(base_addr, reg_val);
- FSpimMaskIrq(base_addr, FSPIM_IMR_ALL_BITS);
- instance_p->length = len;
- instance_p->tx_buff = tx_buf;
- instance_p->tx_buff_end = tx_buf + len;
- instance_p->rx_buff = rx_buf;
- instance_p->rx_buff_end = rx_buf + len;
- FSPIM_DEBUG("tx buff@%p-%d, rx buff@%p-%d",
- instance_p->tx_buff, len,
- instance_p->rx_buff, len);
- FSpimSetEnable(base_addr, TRUE);
- do
- {
- FSpimFifoTx(instance_p);
- FSpimFifoRx(instance_p);
- }
- while (instance_p->rx_buff_end > instance_p->rx_buff);
- return ret;
- }
- /**
- * @name: FSpimTransferByInterrupt
- * @msg: 先发送后接收数据 (中断处理),利用Fifo进行处理
- * @return {FError} FSPIM_SUCCESS表示处理成功,其它返回值表示处理失败
- * @param {FSpim} *instance_p 驱动控制数据
- * @param {void} *tx_buf 写缓冲区
- * @param {void} *rx_buf 读缓冲区
- * @param {fsize_t} len 读写缓冲区长度 (必须相等)
- */
- FError FSpimTransferByInterrupt(FSpim *instance_p, const void *tx_buf, void *rx_buf, fsize_t len)
- {
- FASSERT(instance_p);
- u32 reg_val;
- uintptr base_addr = instance_p->config.base_addr;
- u32 data_width = instance_p->config.n_bytes;
- u32 tx_level;
- if (FT_COMPONENT_IS_READY != instance_p->is_ready)
- {
- FSPIM_ERROR("device is already initialized!!!");
- return FSPIM_ERR_NOT_READY;
- }
- FSpimSetEnable(base_addr, FALSE);
- reg_val = FSpimGetCtrlR0(base_addr);
- reg_val &= ~FSPIM_CTRL_R0_DFS_MASK;
- reg_val |= FSPIM_CTRL_R0_DFS((data_width << 3) - 1);
- reg_val &= ~FSPIM_CTRL_R0_TMOD_MASK;
- if (tx_buf && rx_buf)
- reg_val |= FSPIM_CTRL_R0_TMOD(FSPIM_TMOD_RX_TX);
- else if (rx_buf)
- reg_val |= FSPIM_CTRL_R0_TMOD(FSPIM_TMOD_RX_ONLY);
- else
- reg_val |= FSPIM_CTRL_R0_TMOD(FSPIM_TMOD_RX_TX);
- FSpimSetCtrlR0(base_addr, reg_val);
- FSpimMaskIrq(base_addr, FSPIM_IMR_ALL_BITS);
- instance_p->length = len;
- instance_p->tx_buff = tx_buf;
- instance_p->tx_buff_end = instance_p->tx_buff + len;
- instance_p->rx_buff = rx_buf;
- instance_p->rx_buff_end = instance_p->rx_buff + len;
- /* 设置中断触发的时机,fifo填满一半,或者所有的数据填完 */
- tx_level = min(instance_p->tx_fifo_len / 2, instance_p->length / data_width);
- FSpimSetTxFifoThreshold(base_addr, tx_level);
- FSpimUmaskIrq(base_addr, FSPIM_IMR_TXEIS | FSPIM_IMR_TXOIS | FSPIM_IMR_RXUIS | FSPIM_IMR_RXOIS);
- FSpimSetEnable(base_addr, TRUE);
- return FSPIM_SUCCESS;
- }
- #ifdef FSPIM_VERSION_2 /* E2000 */
- /**
- * @name: FSpimTransferDMA
- * @msg: 启动SPIM DMA数据传输
- * @return {FError} FSPIM_SUCCESS表示启动DMA传输成功,其它值表示失败
- * @param {FSpim} *instance_p, 驱动控制数据
- * @param {boolean} tx, TRUE: 启动发送DMA
- * @param {boolean} rx, TRUE: 启动接收DMA
- */
- FError FSpimTransferDMA(FSpim *instance_p, boolean tx, boolean rx)
- {
- FASSERT(instance_p);
- u32 reg_val;
- uintptr base_addr = instance_p->config.base_addr;
- u32 data_width = instance_p->config.n_bytes;
- if (FT_COMPONENT_IS_READY != instance_p->is_ready)
- {
- FSPIM_ERROR("device is not yet initialized!!!");
- return FSPIM_ERR_NOT_READY;
- }
- FSpimSetEnable(base_addr, FALSE);
- /* set up spim transfer mode */
- reg_val = FSpimGetCtrlR0(base_addr);
- reg_val &= ~FSPIM_CTRL_R0_DFS_MASK;
- reg_val |= FSPIM_CTRL_R0_DFS((data_width << 3) - 1);
- reg_val &= ~FSPIM_CTRL_R0_TMOD_MASK;
- if (tx && rx)
- reg_val |= FSPIM_CTRL_R0_TMOD(FSPIM_TMOD_RX_TX);
- else if (rx)
- reg_val |= FSPIM_CTRL_R0_TMOD(FSPIM_TMOD_RX_ONLY);
- else
- reg_val |= FSPIM_CTRL_R0_TMOD(FSPIM_TMOD_RX_TX);
- FSpimSetCtrlR0(base_addr, reg_val);
- FSpimMaskIrq(base_addr, FSPIM_IMR_ALL_BITS); /* mask all interrupts */
- FSpimSetEnable(base_addr, TRUE);
- /* enable DMA tx / rx */
- reg_val = FSPIM_READ_REG32(base_addr, FSPIM_DMA_CR_OFFSET);
- if (tx)
- reg_val |= FSPIM_DMA_CR_TDMAE;
- else
- reg_val &= ~FSPIM_DMA_CR_TDMAE;
- if (rx)
- reg_val |= FSPIM_DMA_CR_RDMAE;
- else
- reg_val &= ~FSPIM_DMA_CR_RDMAE;
- FSPIM_WRITE_REG32(base_addr, FSPIM_DMA_CR_OFFSET, reg_val);
- FSpimSelSlaveDev(base_addr, instance_p->config.slave_dev_id);
- return FSPIM_SUCCESS;
- }
- /**
- * @name: FSpimSetChipSelection
- * @msg: 设置片选信号
- * @return {NONE}
- * @param {FSpim} *instance_p, 驱动控制数据
- * @param {boolean} on, TRUE: 片选打开, FALSE: 片选关闭
- */
- void FSpimSetChipSelection(FSpim *instance_p, boolean on)
- {
- FASSERT(instance_p);
- u32 reg_val;
- FSpimSlaveDevice cs_n = instance_p->config.slave_dev_id;
- uintptr base_addr = instance_p->config.base_addr;
- if (FT_COMPONENT_IS_READY != instance_p->is_ready)
- {
- FSPIM_ERROR("device is not yet initialized!!!");
- return;
- }
- reg_val = FSPIM_READ_REG32(base_addr, FSPIM_CS_OFFSET);
- if (on)
- {
- reg_val |= FSPIM_CHIP_SEL_EN((u32)cs_n);
- reg_val |= FSPIM_CHIP_SEL((u32)cs_n);
- }
- else
- {
- reg_val &= ~FSPIM_CHIP_SEL_EN((u32)cs_n);
- reg_val &= ~FSPIM_CHIP_SEL((u32)cs_n);
- }
- FSPIM_WRITE_REG32(base_addr, FSPIM_CS_OFFSET, reg_val);
- return;
- }
- #endif
- /**
- * @name: FSpimErrorToMessage
- * @msg: 获取FSPIM模块错误码对应的错误信息
- * @return {const char *}, 错误码信息,NULL表示失败
- * @param {FError} error, FSPIM输入错误码
- */
- const char *FSpimErrorToMessage(FError error)
- {
- const char *msg = NULL;
- if (FSPIM_SUCCESS != error && (FSPIM_ERR_CODE_PREFIX != error & (FT_ERRCODE_SYS_MODULE_MASK | FT_ERRCODE_SUB_MODULE_MASK)))
- {
- /* if input error do not belong to this module */
- return msg;
- }
- u32 index = error & FT_ERRCODE_TAIL_VALUE_MASK;
- if (index < FSPIM_NUM_OF_ERR_CODE)
- {
- msg = FSPIM_ERROR_CODE_MSG[index];
- }
- return msg;
- }
|