Exemplo n.º 1
0
/**
 ****************************************************************************************
 * @brief SPI0 RX interrupt handler.
 * @description
 * If SPI0 RX FIFO is not empty, it then generates interrupt. In this handler, data is received from
 * port SPI0 until expected receiving data size is reduced to zero. After last data received, the callback function is called.
 ****************************************************************************************
 */
void SPI0_IRQHandler(void)
{
#if (CONFIG_SPI0_RX_ENABLE_INTERRUPT==TRUE)
    while ( spi_spi_GetSR(QN_SPI0) & SPI_MASK_RX_FIFO_NEMT_IF ) { // RX FIFO not empty interrupt

        if (spi0_env.rx.size > 0) {

            spi_rx_data(QN_SPI0, (struct spi_env_tag *)&spi0_env);

            if (spi0_env.rx.size <= 0) {
                // Disable RX interrupt
                spi_int_enable(QN_SPI0, SPI_RX_INT, MASK_DISABLE);
                #if SPI_CALLBACK_EN==TRUE
                // Call end of reception callback
                if (spi0_env.rx.callback != NULL)
                {
                    spi0_env.rx.callback();
                }
                #endif
            }
        }
        else {
            spi_spi_GetRXD(QN_SPI0);  // clear interrupt
        }
    }
#endif

    if ( spi_spi_GetSR(QN_SPI0) & SPI_MASK_TX_FIFO_NFUL_IF )   /* TX FIFO not full interrupt */
    {
#if (CONFIG_SPI0_TX_ENABLE_INTERRUPT==TRUE)
        if (spi0_env.tx.size > 0) {

            spi_tx_data(QN_SPI0, (struct spi_env_tag *)&spi0_env);
            NVIC_ClearPendingIRQ(SPI0_TX_IRQn);

            if (spi0_env.tx.size <= 0) {
                // Disable TX interrupt
                spi_int_enable(QN_SPI0, SPI_TX_INT, MASK_DISABLE);
                #if SPI_CALLBACK_EN==TRUE
                // Call end of transmission callback
                if (spi0_env.tx.callback != NULL)
                {
                    spi0_env.tx.callback();
                }
                #endif
            }
        }
        else
#endif
        {
            if ( (spi0_env.mode == SPI_MASTER_MOD)
                && (spi0_env.rx.size > 0) ) {
#if (CONFIG_SPI0_TX_ENABLE_INTERRUPT==FALSE)
                if (spi_check_tx_free(QN_SPI0) == SPI_TX_FREE)
#endif
                spi_spi_SetTXD(QN_SPI0, SPI_DUMMY_DATA);
            }
        }
    }
}
Exemplo n.º 2
0
static void spi_receive_data(QN_SPI_TypeDef * SPI, struct spi_env_tag *spi_env)
{
    while ( spi_env->rx.size > 0 )
    {
        /* As long as Receive FIFO is not empty, we can always receive. */
        /* if it's a peer-to-peer communication, TXD needs to be written before a read can take place. */
        if ( (spi_env->mode == SPI_MASTER_MOD) && (spi_check_tx_free(SPI) == SPI_TX_FREE) ) {
            spi_spi_SetTXD(SPI, SPI_DUMMY_DATA);
            /* Wait until the Busy bit is cleared */
            //while ( spi_spi_GetSR(SPI) & SPI_MASK_BUSY );
        }
        while ( !(spi_spi_GetSR(SPI) & SPI_MASK_RX_FIFO_NEMT_IF) );

        spi_rx_data(SPI, spi_env);
    }

#if SPI_CALLBACK_EN==TRUE
    // Call end of reception callback
    if(spi_env->rx.callback != NULL)
    {
        spi_env->rx.callback();
    }
#endif
}
Exemplo n.º 3
0
/**
 ****************************************************************************************
 * @brief   Check application whether to enter sleep mode
 * @return  sleep allowed status
 ****************************************************************************************
 */
int usr_sleep(void)
{
    int32_t rt;

    rt = sleep_get_pm();

    // If the BLE timer queue is not NULL, prevent entering into DEEPSLEEP mode
    if(rt == PM_DEEP_SLEEP && !ke_timer_empty())
    {
        rt = PM_SLEEP;
    }

    // Check Device status
    if((rt >= PM_SLEEP)
       && dev_get_bf())
    {
        // If any devices are still working, the chip cann't enter into SLEEP/DEEPSLEEP mode.
        rt = PM_IDLE;
    }

    if ((rt >= PM_SLEEP) && (!gpio_sleep_allowed()))
    {
        return PM_ACTIVE;    // If CLOCK OFF & POWER DOWN is disabled, return immediately
    }

#if QN_DBG_PRINT
    int uart_tx_st = uart_check_tx_free(QN_DEBUG_UART);
    
    if((rt >= PM_SLEEP) && (uart_tx_st == UART_TX_BUF_BUSY))
    {
        rt = PM_IDLE;
    }
    else if(uart_tx_st == UART_LAST_BYTE_ONGOING)
    {
        return PM_ACTIVE;    // If CLOCK OFF & POWER DOWN is disabled, return immediately
    }
#endif

#if QN_EACI
    if ((rt >= PM_SLEEP) &&
        (  (eaci_env.tx_state!=EACI_STATE_TX_IDLE)              // Check EACI UART TX status
        || (eaci_env.rx_state!=EACI_STATE_RX_START)) )          // Check EACI UART RX status
    {
        rt = PM_IDLE;
    }

    int tx_st = 0;
    #if (defined(CFG_HCI_UART))
    tx_st = uart_check_tx_free(QN_HCI_PORT);
    if ((rt >= PM_SLEEP) && (tx_st == UART_TX_BUF_BUSY))
    {
        rt = PM_IDLE;
    }
    else if (tx_st == UART_LAST_BYTE_ONGOING)
    {
        return PM_ACTIVE;    // If CLOCK OFF & POWER DOWN is disabled, return immediately
    }
    #elif (defined(CFG_HCI_SPI))
    tx_st = spi_check_tx_free(QN_HCI_PORT);
    if ((rt >= PM_SLEEP) && (tx_st == SPI_TX_BUF_BUSY))
    {
        rt = PM_IDLE;
    }
    else if (tx_st == SPI_LAST_BYTE_ONGOING)
    {
        return PM_ACTIVE;    // If CLOCK OFF & POWER DOWN is disabled, return immediately
    }
    #endif

#endif

    return rt;
}