/**************************************************************************//** * @file qspi.c * @version V3.00 * @brief M2351 series QSPI driver source file * * @copyright SPDX-License-Identifier: Apache-2.0 * @copyright Copyright (C) 2017-2020 Nuvoton Technology Corp. All rights reserved. *****************************************************************************/ #include "NuMicro.h" /** @addtogroup Standard_Driver Standard Driver @{ */ /** @addtogroup QSPI_Driver QSPI Driver @{ */ /** @addtogroup QSPI_EXPORTED_FUNCTIONS QSPI Exported Functions @{ */ /** * @brief This function make QSPI module be ready to transfer. * @param[in] qspi The pointer of the specified QSPI module. * @param[in] u32MasterSlave Decides the QSPI module is operating in master mode or in slave mode. (QSPI_SLAVE, QSPI_MASTER) * @param[in] u32QSPIMode Decides the transfer timing. (QSPI_MODE_0, QSPI_MODE_1, QSPI_MODE_2, QSPI_MODE_3) * @param[in] u32DataWidth Decides the data width of a QSPI transaction. * @param[in] u32BusClock The expected frequency of QSPI bus clock in Hz. * @return Actual frequency of QSPI peripheral clock. * @details By default, the QSPI transfer sequence is MSB first, the slave selection signal is active low and the automatic * slave selection function is disabled. * In Slave mode, the u32BusClock shall be NULL and the QSPI clock divider setting will be 0. * The actual clock rate may be different from the target QSPI clock rate. * For example, if the QSPI source clock rate is 12 MHz and the target QSPI bus clock rate is 7 MHz, the * actual QSPI clock rate will be 6MHz. If u32BusClock = 0, DIVIDER setting will be set to the maximum value. If u32BusClock >= system clock frequency for Secure, QSPI peripheral clock source will be set to APB clock and DIVIDER will be set to 0. If u32BusClock >= system clock frequency for Non-Secure, this function does not do anything to avoid the situation that the frequency of * QSPI bus clock cannot be faster than the system clock rate. User should set up carefully. If u32BusClock >= QSPI peripheral clock source, DIVIDER will be set to 0. In slave mode for Secure, the QSPI peripheral clock rate will equal to APB clock rate. In slave mode for Non-Secure, the QSPI peripheral clock rate will equal to the clock rate set in secure mode. */ uint32_t QSPI_Open(QSPI_T *qspi, uint32_t u32MasterSlave, uint32_t u32QSPIMode, uint32_t u32DataWidth, uint32_t u32BusClock) { uint32_t u32ClkSrc = 0UL, u32Div, u32HCLKFreq, u32PCLK0Freq, u32RetValue = 0UL; if(u32DataWidth == 32UL) { u32DataWidth = 0UL; } /* Get system clock frequency */ u32HCLKFreq = CLK_GetHCLKFreq(); /* Get APB0 clock frequency */ u32PCLK0Freq = CLK_GetPCLK0Freq(); if(u32MasterSlave == QSPI_MASTER) { /* Default setting: slave selection signal is active low; disable automatic slave selection function. */ qspi->SSCTL = QSPI_SS_ACTIVE_LOW; /* Default setting: MSB first, disable unit transfer interrupt, SP_CYCLE = 0. */ qspi->CTL = u32MasterSlave | (u32DataWidth << QSPI_CTL_DWIDTH_Pos) | (u32QSPIMode) | QSPI_CTL_SPIEN_Msk; if(u32BusClock >= u32HCLKFreq) { if(!(__PC() & NS_OFFSET)) { /* Select PCLK as the clock source of QSPI */ if((qspi == QSPI0) || (qspi == QSPI0_NS)) { CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_QSPI0SEL_Msk)) | CLK_CLKSEL2_QSPI0SEL_PCLK0; } } } /* Check clock source of QSPI */ if((qspi == QSPI0) || (qspi == QSPI0_NS)) { if((CLK_GetModuleClockSource(QSPI0_MODULE) << CLK_CLKSEL2_QSPI0SEL_Pos) == CLK_CLKSEL2_QSPI0SEL_HXT) { u32ClkSrc = __HXT; /* Clock source is HXT */ } else if((CLK_GetModuleClockSource(QSPI0_MODULE) << CLK_CLKSEL2_QSPI0SEL_Pos) == CLK_CLKSEL2_QSPI0SEL_PLL) { u32ClkSrc = CLK_GetPLLClockFreq(); /* Clock source is PLL */ } else if((CLK_GetModuleClockSource(QSPI0_MODULE) << CLK_CLKSEL2_QSPI0SEL_Pos) == CLK_CLKSEL2_QSPI0SEL_PCLK0) { u32ClkSrc = CLK_GetPCLK0Freq(); /* Clock source is PCLK0 */ } else { u32ClkSrc = __HIRC; /* Clock source is HIRC */ } } if(u32BusClock >= u32HCLKFreq) { /* Set DIVIDER = 0 */ qspi->CLKDIV = 0UL; /* Return master peripheral clock rate */ u32RetValue = u32ClkSrc; } else if(u32BusClock >= u32ClkSrc) { /* Set DIVIDER = 0 */ qspi->CLKDIV = 0UL; /* Return master peripheral clock rate */ u32RetValue = u32ClkSrc; } else if(u32BusClock == 0UL) { /* Set DIVIDER to the maximum value 0x1FF. f_spi = f_spi_clk_src / (DIVIDER + 1) */ qspi->CLKDIV |= QSPI_CLKDIV_DIVIDER_Msk; /* Return master peripheral clock rate */ u32RetValue = (u32ClkSrc / (0x1FFUL + 1UL)); } else { u32Div = (((u32ClkSrc * 10UL) / u32BusClock + 5UL) / 10UL) - 1UL; /* Round to the nearest integer */ if(u32Div > 0x1FFUL) { u32Div = 0x1FFUL; qspi->CLKDIV |= QSPI_CLKDIV_DIVIDER_Msk; /* Return master peripheral clock rate */ u32RetValue = (u32ClkSrc / (0x1FFUL + 1UL)); } else { qspi->CLKDIV = (qspi->CLKDIV & (~QSPI_CLKDIV_DIVIDER_Msk)) | (u32Div << QSPI_CLKDIV_DIVIDER_Pos); /* Return master peripheral clock rate */ u32RetValue = (u32ClkSrc / (u32Div + 1UL)); } } } else /* For slave mode, force the QSPI peripheral clock rate to equal APB clock rate. */ { /* Default setting: slave selection signal is low level active. */ qspi->SSCTL = QSPI_SS_ACTIVE_LOW; /* Default setting: MSB first, disable unit transfer interrupt, SP_CYCLE = 0. */ qspi->CTL = u32MasterSlave | (u32DataWidth << QSPI_CTL_DWIDTH_Pos) | (u32QSPIMode) | QSPI_CTL_SPIEN_Msk; /* Set DIVIDER = 0 */ qspi->CLKDIV = 0UL; if(!(__PC() & NS_OFFSET)) { /* Select PCLK as the clock source of QSPI */ if((qspi == QSPI0) || (qspi == QSPI0_NS)) { CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_QSPI0SEL_Msk)) | CLK_CLKSEL2_QSPI0SEL_PCLK0; /* Return slave peripheral clock rate */ u32RetValue = u32PCLK0Freq; } } else { /* Check clock source of QSPI */ if((qspi == QSPI0) || (qspi == QSPI0_NS)) { if((CLK_GetModuleClockSource(QSPI0_MODULE) << CLK_CLKSEL2_QSPI0SEL_Pos) == CLK_CLKSEL2_QSPI0SEL_HXT) { u32RetValue = __HXT; /* Clock source is HXT */ } else if((CLK_GetModuleClockSource(QSPI0_MODULE) << CLK_CLKSEL2_QSPI0SEL_Pos) == CLK_CLKSEL2_QSPI0SEL_PLL) { u32RetValue = CLK_GetPLLClockFreq(); /* Clock source is PLL */ } else if((CLK_GetModuleClockSource(QSPI0_MODULE) << CLK_CLKSEL2_QSPI0SEL_Pos) == CLK_CLKSEL2_QSPI0SEL_PCLK0) { u32RetValue = u32PCLK0Freq; /* Clock source is PCLK0 */ } else { u32RetValue = __HIRC; /* Clock source is HIRC */ } } } } return u32RetValue; } /** * @brief Disable QSPI controller. * @param[in] qspi The pointer of the specified QSPI module. * @return None * @details Clear SPIEN bit of QSPI_CTL register to disable QSPI transfer control. */ void QSPI_Close(QSPI_T *qspi) { qspi->CTL &= ~QSPI_CTL_SPIEN_Msk; } /** * @brief Clear RX FIFO buffer. * @param[in] qspi The pointer of the specified QSPI module. * @return None * @details This function will clear QSPI RX FIFO buffer. The RXEMPTY (QSPI_STATUS[8]) will be set to 1. */ void QSPI_ClearRxFIFO(QSPI_T *qspi) { qspi->FIFOCTL |= QSPI_FIFOCTL_RXFBCLR_Msk; } /** * @brief Clear TX FIFO buffer. * @param[in] qspi The pointer of the specified QSPI module. * @return None * @details This function will clear QSPI TX FIFO buffer. The TXEMPTY (QSPI_STATUS[16]) will be set to 1. The TX shift register will not be cleared. */ void QSPI_ClearTxFIFO(QSPI_T *qspi) { qspi->FIFOCTL |= QSPI_FIFOCTL_TXFBCLR_Msk; } /** * @brief Disable the automatic slave selection function. * @param[in] qspi The pointer of the specified QSPI module. * @return None * @details This function will disable the automatic slave selection function and set slave selection signal to inactive state. */ void QSPI_DisableAutoSS(QSPI_T *qspi) { qspi->SSCTL &= ~(QSPI_SSCTL_AUTOSS_Msk | QSPI_SSCTL_SS_Msk); } /** * @brief Enable the automatic slave selection function. * @param[in] qspi The pointer of the specified QSPI module. * @param[in] u32SSPinMask Specifies slave selection pins. (QSPI_SS) * @param[in] u32ActiveLevel Specifies the active level of slave selection signal. (QSPI_SS_ACTIVE_HIGH, QSPI_SS_ACTIVE_LOW) * @return None * @details This function will enable the automatic slave selection function. Only available in Master mode. * The slave selection pin and the active level will be set in this function. */ void QSPI_EnableAutoSS(QSPI_T *qspi, uint32_t u32SSPinMask, uint32_t u32ActiveLevel) { qspi->SSCTL = (qspi->SSCTL & (~(QSPI_SSCTL_AUTOSS_Msk | QSPI_SSCTL_SSACTPOL_Msk | QSPI_SSCTL_SS_Msk))) | (u32SSPinMask | u32ActiveLevel | QSPI_SSCTL_AUTOSS_Msk); } /** * @brief Set the QSPI bus clock. * @param[in] qspi The pointer of the specified QSPI module. * @param[in] u32BusClock The expected frequency of QSPI bus clock in Hz. * @return Actual frequency of QSPI bus clock. * @details This function is only available in Master mode. The actual clock rate may be different from the target QSPI bus clock rate. * For example, if the QSPI source clock rate is 12 MHz and the target QSPI bus clock rate is 7 MHz, the actual QSPI bus clock * rate will be 6 MHz. If u32BusClock = 0, DIVIDER setting will be set to the maximum value. If u32BusClock >= system clock frequency for Secure, QSPI peripheral clock source will be set to APB clock and DIVIDER will be set to 0. If u32BusClock >= system clock frequency for Non-Secure, this function does not do anything to avoid the situation that the frequency of * QSPI bus clock cannot be faster than the system clock rate. User should set up carefully. If u32BusClock >= QSPI peripheral clock source, DIVIDER will be set to 0. */ uint32_t QSPI_SetBusClock(QSPI_T *qspi, uint32_t u32BusClock) { uint32_t u32ClkSrc, u32HCLKFreq; uint32_t u32Div, u32RetValue; /* Check if valid QSPI exist */ if(!((qspi == QSPI0) || (qspi == QSPI0_NS))) { return 0UL; } /* Get system clock frequency */ u32HCLKFreq = CLK_GetHCLKFreq(); if(u32BusClock >= u32HCLKFreq) { if(!(__PC() & NS_OFFSET)) { /* Select PCLK as the clock source of QSPI */ CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_QSPI0SEL_Msk)) | CLK_CLKSEL2_QSPI0SEL_PCLK0; } } /* Check clock source of QSPI */ if((CLK_GetModuleClockSource(QSPI0_MODULE) << CLK_CLKSEL2_QSPI0SEL_Pos) == CLK_CLKSEL2_QSPI0SEL_HXT) { u32ClkSrc = __HXT; /* Clock source is HXT */ } else if((CLK_GetModuleClockSource(QSPI0_MODULE) << CLK_CLKSEL2_QSPI0SEL_Pos) == CLK_CLKSEL2_QSPI0SEL_PLL) { u32ClkSrc = CLK_GetPLLClockFreq(); /* Clock source is PLL */ } else if((CLK_GetModuleClockSource(QSPI0_MODULE) << CLK_CLKSEL2_QSPI0SEL_Pos) == CLK_CLKSEL2_QSPI0SEL_PCLK0) { u32ClkSrc = CLK_GetPCLK0Freq(); /* Clock source is PCLK0 */ } else { u32ClkSrc = __HIRC; /* Clock source is HIRC */ } if(u32BusClock >= u32HCLKFreq) { /* Set DIVIDER = 0 */ qspi->CLKDIV = 0UL; /* Return master peripheral clock rate */ u32RetValue = u32ClkSrc; } else if(u32BusClock >= u32ClkSrc) { /* Set DIVIDER = 0 */ qspi->CLKDIV = 0UL; /* Return master peripheral clock rate */ u32RetValue = u32ClkSrc; } else if(u32BusClock == 0UL) { /* Set DIVIDER to the maximum value 0x1FF. f_spi = f_spi_clk_src / (DIVIDER + 1) */ qspi->CLKDIV |= QSPI_CLKDIV_DIVIDER_Msk; /* Return master peripheral clock rate */ u32RetValue = (u32ClkSrc / (0x1FFUL + 1UL)); } else { u32Div = (((u32ClkSrc * 10UL) / u32BusClock + 5UL) / 10UL) - 1UL; /* Round to the nearest integer */ if(u32Div > 0x1FFUL) { u32Div = 0x1FFUL; qspi->CLKDIV |= QSPI_CLKDIV_DIVIDER_Msk; /* Return master peripheral clock rate */ u32RetValue = (u32ClkSrc / (0x1FFUL + 1UL)); } else { qspi->CLKDIV = (qspi->CLKDIV & (~QSPI_CLKDIV_DIVIDER_Msk)) | (u32Div << QSPI_CLKDIV_DIVIDER_Pos); /* Return master peripheral clock rate */ u32RetValue = (u32ClkSrc / (u32Div + 1UL)); } } return u32RetValue; } /** * @brief Configure FIFO threshold setting. * @param[in] qspi The pointer of the specified QSPI module. * @param[in] u32TxThreshold Decides the TX FIFO threshold. It could be 0 ~ 7. * @param[in] u32RxThreshold Decides the RX FIFO threshold. It could be 0 ~ 7. * @return None * @details Set TX FIFO threshold and RX FIFO threshold configurations. */ void QSPI_SetFIFO(QSPI_T *qspi, uint32_t u32TxThreshold, uint32_t u32RxThreshold) { qspi->FIFOCTL = (qspi->FIFOCTL & ~(QSPI_FIFOCTL_TXTH_Msk | QSPI_FIFOCTL_RXTH_Msk)) | (u32TxThreshold << QSPI_FIFOCTL_TXTH_Pos) | (u32RxThreshold << QSPI_FIFOCTL_RXTH_Pos); } /** * @brief Get the actual frequency of QSPI bus clock. Only available in Master mode. * @param[in] qspi The pointer of the specified QSPI module. * @return Actual QSPI bus clock frequency in Hz. * @details This function will calculate the actual QSPI bus clock rate according to the QQSPISEL/QSPIxSEL and DIVIDER settings. Only available in Master mode. */ uint32_t QSPI_GetBusClock(QSPI_T *qspi) { uint32_t u32Div; uint32_t u32ClkSrc; /* Check if valid QSPI exist */ if(!((qspi == QSPI0) || (qspi == QSPI0_NS))) { return 0UL; } /* Get DIVIDER setting */ u32Div = (qspi->CLKDIV & QSPI_CLKDIV_DIVIDER_Msk) >> QSPI_CLKDIV_DIVIDER_Pos; /* Check clock source of QSPI */ if((CLK_GetModuleClockSource(QSPI0_MODULE) << CLK_CLKSEL2_QSPI0SEL_Pos) == CLK_CLKSEL2_QSPI0SEL_HXT) { u32ClkSrc = __HXT; /* Clock source is HXT */ } else if((CLK_GetModuleClockSource(QSPI0_MODULE) << CLK_CLKSEL2_QSPI0SEL_Pos) == CLK_CLKSEL2_QSPI0SEL_PLL) { u32ClkSrc = CLK_GetPLLClockFreq(); /* Clock source is PLL */ } else if((CLK_GetModuleClockSource(QSPI0_MODULE) << CLK_CLKSEL2_QSPI0SEL_Pos) == CLK_CLKSEL2_QSPI0SEL_PCLK0) { u32ClkSrc = CLK_GetPCLK0Freq(); /* Clock source is PCLK0 */ } else { u32ClkSrc = __HIRC; /* Clock source is HIRC */ } /* Return QSPI bus clock rate */ return (u32ClkSrc / (u32Div + 1UL)); } /** * @brief Enable interrupt function. * @param[in] qspi The pointer of the specified QSPI module. * @param[in] u32Mask The combination of all related interrupt enable bits. * Each bit corresponds to a interrupt enable bit. * This parameter decides which interrupts will be enabled. It is combination of: * - \ref QSPI_UNIT_INT_MASK * - \ref QSPI_SSACT_INT_MASK * - \ref QSPI_SSINACT_INT_MASK * - \ref QSPI_SLVUR_INT_MASK * - \ref QSPI_SLVBE_INT_MASK * - \ref QSPI_SLVTO_INT_MASK * - \ref QSPI_TXUF_INT_MASK * - \ref QSPI_FIFO_TXTH_INT_MASK * - \ref QSPI_FIFO_RXTH_INT_MASK * - \ref QSPI_FIFO_RXOV_INT_MASK * - \ref QSPI_FIFO_RXTO_INT_MASK * * @return None * @details Enable QSPI related interrupts specified by u32Mask parameter. */ void QSPI_EnableInt(QSPI_T *qspi, uint32_t u32Mask) { /* Enable unit transfer interrupt flag */ if((u32Mask & QSPI_UNIT_INT_MASK) == QSPI_UNIT_INT_MASK) { qspi->CTL |= QSPI_CTL_UNITIEN_Msk; } /* Enable slave selection signal active interrupt flag */ if((u32Mask & QSPI_SSACT_INT_MASK) == QSPI_SSACT_INT_MASK) { qspi->SSCTL |= QSPI_SSCTL_SSACTIEN_Msk; } /* Enable slave selection signal inactive interrupt flag */ if((u32Mask & QSPI_SSINACT_INT_MASK) == QSPI_SSINACT_INT_MASK) { qspi->SSCTL |= QSPI_SSCTL_SSINAIEN_Msk; } /* Enable slave TX under run interrupt flag */ if((u32Mask & QSPI_SLVUR_INT_MASK) == QSPI_SLVUR_INT_MASK) { qspi->SSCTL |= QSPI_SSCTL_SLVURIEN_Msk; } /* Enable slave bit count error interrupt flag */ if((u32Mask & QSPI_SLVBE_INT_MASK) == QSPI_SLVBE_INT_MASK) { qspi->SSCTL |= QSPI_SSCTL_SLVBEIEN_Msk; } /* Enable slave mode time-out interrupt flag */ if((u32Mask & QSPI_SLVTO_INT_MASK) == QSPI_SLVTO_INT_MASK) { qspi->SSCTL |= QSPI_SSCTL_SLVTOIEN_Msk; } /* Enable slave TX underflow interrupt flag */ if((u32Mask & QSPI_TXUF_INT_MASK) == QSPI_TXUF_INT_MASK) { qspi->FIFOCTL |= QSPI_FIFOCTL_TXUFIEN_Msk; } /* Enable TX threshold interrupt flag */ if((u32Mask & QSPI_FIFO_TXTH_INT_MASK) == QSPI_FIFO_TXTH_INT_MASK) { qspi->FIFOCTL |= QSPI_FIFOCTL_TXTHIEN_Msk; } /* Enable RX threshold interrupt flag */ if((u32Mask & QSPI_FIFO_RXTH_INT_MASK) == QSPI_FIFO_RXTH_INT_MASK) { qspi->FIFOCTL |= QSPI_FIFOCTL_RXTHIEN_Msk; } /* Enable RX overrun interrupt flag */ if((u32Mask & QSPI_FIFO_RXOV_INT_MASK) == QSPI_FIFO_RXOV_INT_MASK) { qspi->FIFOCTL |= QSPI_FIFOCTL_RXOVIEN_Msk; } /* Enable RX time-out interrupt flag */ if((u32Mask & QSPI_FIFO_RXTO_INT_MASK) == QSPI_FIFO_RXTO_INT_MASK) { qspi->FIFOCTL |= QSPI_FIFOCTL_RXTOIEN_Msk; } } /** * @brief Disable interrupt function. * @param[in] qspi The pointer of the specified QSPI module. * @param[in] u32Mask The combination of all related interrupt enable bits. * Each bit corresponds to a interrupt bit. * This parameter decides which interrupts will be disabled. It is combination of: * - \ref QSPI_UNIT_INT_MASK * - \ref QSPI_SSACT_INT_MASK * - \ref QSPI_SSINACT_INT_MASK * - \ref QSPI_SLVUR_INT_MASK * - \ref QSPI_SLVBE_INT_MASK * - \ref QSPI_SLVTO_INT_MASK * - \ref QSPI_TXUF_INT_MASK * - \ref QSPI_FIFO_TXTH_INT_MASK * - \ref QSPI_FIFO_RXTH_INT_MASK * - \ref QSPI_FIFO_RXOV_INT_MASK * - \ref QSPI_FIFO_RXTO_INT_MASK * * @return None * @details Disable QSPI related interrupts specified by u32Mask parameter. */ void QSPI_DisableInt(QSPI_T *qspi, uint32_t u32Mask) { /* Disable unit transfer interrupt flag */ if((u32Mask & QSPI_UNIT_INT_MASK) == QSPI_UNIT_INT_MASK) { qspi->CTL &= ~QSPI_CTL_UNITIEN_Msk; } /* Disable slave selection signal active interrupt flag */ if((u32Mask & QSPI_SSACT_INT_MASK) == QSPI_SSACT_INT_MASK) { qspi->SSCTL &= ~QSPI_SSCTL_SSACTIEN_Msk; } /* Disable slave selection signal inactive interrupt flag */ if((u32Mask & QSPI_SSINACT_INT_MASK) == QSPI_SSINACT_INT_MASK) { qspi->SSCTL &= ~QSPI_SSCTL_SSINAIEN_Msk; } /* Disable slave TX under run interrupt flag */ if((u32Mask & QSPI_SLVUR_INT_MASK) == QSPI_SLVUR_INT_MASK) { qspi->SSCTL &= ~QSPI_SSCTL_SLVURIEN_Msk; } /* Disable slave bit count error interrupt flag */ if((u32Mask & QSPI_SLVBE_INT_MASK) == QSPI_SLVBE_INT_MASK) { qspi->SSCTL &= ~QSPI_SSCTL_SLVBEIEN_Msk; } /* Disable slave mode time-out interrupt flag */ if((u32Mask & QSPI_SLVTO_INT_MASK) == QSPI_SLVTO_INT_MASK) { qspi->SSCTL &= ~QSPI_SSCTL_SLVTOIEN_Msk; } /* Disable slave TX underflow interrupt flag */ if((u32Mask & QSPI_TXUF_INT_MASK) == QSPI_TXUF_INT_MASK) { qspi->FIFOCTL &= ~QSPI_FIFOCTL_TXUFIEN_Msk; } /* Disable TX threshold interrupt flag */ if((u32Mask & QSPI_FIFO_TXTH_INT_MASK) == QSPI_FIFO_TXTH_INT_MASK) { qspi->FIFOCTL &= ~QSPI_FIFOCTL_TXTHIEN_Msk; } /* Disable RX threshold interrupt flag */ if((u32Mask & QSPI_FIFO_RXTH_INT_MASK) == QSPI_FIFO_RXTH_INT_MASK) { qspi->FIFOCTL &= ~QSPI_FIFOCTL_RXTHIEN_Msk; } /* Disable RX overrun interrupt flag */ if((u32Mask & QSPI_FIFO_RXOV_INT_MASK) == QSPI_FIFO_RXOV_INT_MASK) { qspi->FIFOCTL &= ~QSPI_FIFOCTL_RXOVIEN_Msk; } /* Disable RX time-out interrupt flag */ if((u32Mask & QSPI_FIFO_RXTO_INT_MASK) == QSPI_FIFO_RXTO_INT_MASK) { qspi->FIFOCTL &= ~QSPI_FIFOCTL_RXTOIEN_Msk; } } /** * @brief Get interrupt flag. * @param[in] qspi The pointer of the specified QSPI module. * @param[in] u32Mask The combination of all related interrupt sources. * Each bit corresponds to a interrupt source. * This parameter decides which interrupt flags will be read. It is combination of: * - \ref QSPI_UNIT_INT_MASK * - \ref QSPI_SSACT_INT_MASK * - \ref QSPI_SSINACT_INT_MASK * - \ref QSPI_SLVUR_INT_MASK * - \ref QSPI_SLVBE_INT_MASK * - \ref QSPI_SLVTO_INT_MASK * - \ref QSPI_TXUF_INT_MASK * - \ref QSPI_FIFO_TXTH_INT_MASK * - \ref QSPI_FIFO_RXTH_INT_MASK * - \ref QSPI_FIFO_RXOV_INT_MASK * - \ref QSPI_FIFO_RXTO_INT_MASK * * @return Interrupt flags of selected sources. * @details Get QSPI related interrupt flags specified by u32Mask parameter. */ uint32_t QSPI_GetIntFlag(QSPI_T *qspi, uint32_t u32Mask) { uint32_t u32IntStatus; uint32_t u32IntFlag = 0UL; u32IntStatus = qspi->STATUS; /* Check unit transfer interrupt flag */ if((u32Mask & QSPI_UNIT_INT_MASK) && (u32IntStatus & QSPI_STATUS_UNITIF_Msk)) { u32IntFlag |= QSPI_UNIT_INT_MASK; } /* Check slave selection signal active interrupt flag */ if((u32Mask & QSPI_SSACT_INT_MASK) && (u32IntStatus & QSPI_STATUS_SSACTIF_Msk)) { u32IntFlag |= QSPI_SSACT_INT_MASK; } /* Check slave selection signal inactive interrupt flag */ if((u32Mask & QSPI_SSINACT_INT_MASK) && (u32IntStatus & QSPI_STATUS_SSINAIF_Msk)) { u32IntFlag |= QSPI_SSINACT_INT_MASK; } /* Check slave TX under run interrupt flag */ if((u32Mask & QSPI_SLVUR_INT_MASK) && (u32IntStatus & QSPI_STATUS_SLVURIF_Msk)) { u32IntFlag |= QSPI_SLVUR_INT_MASK; } /* Check slave bit count error interrupt flag */ if((u32Mask & QSPI_SLVBE_INT_MASK) && (u32IntStatus & QSPI_STATUS_SLVBEIF_Msk)) { u32IntFlag |= QSPI_SLVBE_INT_MASK; } /* Check slave mode time-out interrupt flag */ if((u32Mask & QSPI_SLVTO_INT_MASK) && (u32IntStatus & QSPI_STATUS_SLVTOIF_Msk)) { u32IntFlag |= QSPI_SLVTO_INT_MASK; } /* Check slave TX underflow interrupt flag */ if((u32Mask & QSPI_TXUF_INT_MASK) && (u32IntStatus & QSPI_STATUS_TXUFIF_Msk)) { u32IntFlag |= QSPI_TXUF_INT_MASK; } /* Check TX threshold interrupt flag */ if((u32Mask & QSPI_FIFO_TXTH_INT_MASK) && (u32IntStatus & QSPI_STATUS_TXTHIF_Msk)) { u32IntFlag |= QSPI_FIFO_TXTH_INT_MASK; } /* Check RX threshold interrupt flag */ if((u32Mask & QSPI_FIFO_RXTH_INT_MASK) && (u32IntStatus & QSPI_STATUS_RXTHIF_Msk)) { u32IntFlag |= QSPI_FIFO_RXTH_INT_MASK; } /* Check RX overrun interrupt flag */ if((u32Mask & QSPI_FIFO_RXOV_INT_MASK) && (u32IntStatus & QSPI_STATUS_RXOVIF_Msk)) { u32IntFlag |= QSPI_FIFO_RXOV_INT_MASK; } /* Check RX time-out interrupt flag */ if((u32Mask & QSPI_FIFO_RXTO_INT_MASK) && (u32IntStatus & QSPI_STATUS_RXTOIF_Msk)) { u32IntFlag |= QSPI_FIFO_RXTO_INT_MASK; } return u32IntFlag; } /** * @brief Clear interrupt flag. * @param[in] qspi The pointer of the specified QSPI module. * @param[in] u32Mask The combination of all related interrupt sources. * Each bit corresponds to a interrupt source. * This parameter decides which interrupt flags will be cleared. It could be the combination of: * - \ref QSPI_UNIT_INT_MASK * - \ref QSPI_SSACT_INT_MASK * - \ref QSPI_SSINACT_INT_MASK * - \ref QSPI_SLVUR_INT_MASK * - \ref QSPI_SLVBE_INT_MASK * - \ref QSPI_SLVTO_INT_MASK * - \ref QSPI_TXUF_INT_MASK * - \ref QSPI_FIFO_RXOV_INT_MASK * - \ref QSPI_FIFO_RXTO_INT_MASK * * @return None * @details Clear QSPI related interrupt flags specified by u32Mask parameter. */ void QSPI_ClearIntFlag(QSPI_T *qspi, uint32_t u32Mask) { if(u32Mask & QSPI_UNIT_INT_MASK) { qspi->STATUS = QSPI_STATUS_UNITIF_Msk; /* Clear unit transfer interrupt flag */ } if(u32Mask & QSPI_SSACT_INT_MASK) { qspi->STATUS = QSPI_STATUS_SSACTIF_Msk; /* Clear slave selection signal active interrupt flag */ } if(u32Mask & QSPI_SSINACT_INT_MASK) { qspi->STATUS = QSPI_STATUS_SSINAIF_Msk; /* Clear slave selection signal inactive interrupt flag */ } if(u32Mask & QSPI_SLVUR_INT_MASK) { qspi->STATUS = QSPI_STATUS_SLVURIF_Msk; /* Clear slave TX under run interrupt flag */ } if(u32Mask & QSPI_SLVBE_INT_MASK) { qspi->STATUS = QSPI_STATUS_SLVBEIF_Msk; /* Clear slave bit count error interrupt flag */ } if(u32Mask & QSPI_SLVTO_INT_MASK) { qspi->STATUS = QSPI_STATUS_SLVTOIF_Msk; /* Clear slave mode time-out interrupt flag */ } if(u32Mask & QSPI_TXUF_INT_MASK) { qspi->STATUS = QSPI_STATUS_TXUFIF_Msk; /* Clear slave TX underflow interrupt flag */ } if(u32Mask & QSPI_FIFO_RXOV_INT_MASK) { qspi->STATUS = QSPI_STATUS_RXOVIF_Msk; /* Clear RX overrun interrupt flag */ } if(u32Mask & QSPI_FIFO_RXTO_INT_MASK) { qspi->STATUS = QSPI_STATUS_RXTOIF_Msk; /* Clear RX time-out interrupt flag */ } } /** * @brief Get QSPI status. * @param[in] qspi The pointer of the specified QSPI module. * @param[in] u32Mask The combination of all related sources. * Each bit corresponds to a source. * This parameter decides which flags will be read. It is combination of: * - \ref QSPI_BUSY_MASK * - \ref QSPI_RX_EMPTY_MASK * - \ref QSPI_RX_FULL_MASK * - \ref QSPI_TX_EMPTY_MASK * - \ref QSPI_TX_FULL_MASK * - \ref QSPI_TXRX_RESET_MASK * - \ref QSPI_SPIEN_STS_MASK * - \ref QSPI_SSLINE_STS_MASK * * @return Flags of selected sources. * @details Get QSPI related status specified by u32Mask parameter. */ uint32_t QSPI_GetStatus(QSPI_T *qspi, uint32_t u32Mask) { uint32_t u32TmpStatus; uint32_t u32Flag = 0UL; u32TmpStatus = qspi->STATUS; /* Check busy status */ if((u32Mask & QSPI_BUSY_MASK) && (u32TmpStatus & QSPI_STATUS_BUSY_Msk)) { u32Flag |= QSPI_BUSY_MASK; } /* Check RX empty flag */ if((u32Mask & QSPI_RX_EMPTY_MASK) && (u32TmpStatus & QSPI_STATUS_RXEMPTY_Msk)) { u32Flag |= QSPI_RX_EMPTY_MASK; } /* Check RX full flag */ if((u32Mask & QSPI_RX_FULL_MASK) && (u32TmpStatus & QSPI_STATUS_RXFULL_Msk)) { u32Flag |= QSPI_RX_FULL_MASK; } /* Check TX empty flag */ if((u32Mask & QSPI_TX_EMPTY_MASK) && (u32TmpStatus & QSPI_STATUS_TXEMPTY_Msk)) { u32Flag |= QSPI_TX_EMPTY_MASK; } /* Check TX full flag */ if((u32Mask & QSPI_TX_FULL_MASK) && (u32TmpStatus & QSPI_STATUS_TXFULL_Msk)) { u32Flag |= QSPI_TX_FULL_MASK; } /* Check TX/RX reset flag */ if((u32Mask & QSPI_TXRX_RESET_MASK) && (u32TmpStatus & QSPI_STATUS_TXRXRST_Msk)) { u32Flag |= QSPI_TXRX_RESET_MASK; } /* Check SPIEN flag */ if((u32Mask & QSPI_SPIEN_STS_MASK) && (u32TmpStatus & QSPI_STATUS_SPIENSTS_Msk)) { u32Flag |= QSPI_SPIEN_STS_MASK; } /* Check QSPIx_SS line status */ if((u32Mask & QSPI_SSLINE_STS_MASK) && (u32TmpStatus & QSPI_STATUS_SSLINE_Msk)) { u32Flag |= QSPI_SSLINE_STS_MASK; } return u32Flag; } /*@}*/ /* end of group QSPI_EXPORTED_FUNCTIONS */ /*@}*/ /* end of group QSPI_Driver */ /*@}*/ /* end of group Standard_Driver */