/** **************************************************************************************** * @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); } } } }
/* * Main Program */ int main (void) { uint32_t j; uint8_t txbuffer[40]; uint8_t rxbuffer[40]; SystemInit(); for (j = 0; j < 40; j++) { rxbuffer[j] = 0; txbuffer[j] = 0x55 + j; } #if CFG_SPI_TEST_MODE_MASTER_EN //Initialize SPI spi_init(SPI_TEST_PORT, SPI_BITRATE(1000000), SPI_8BIT, SPI_MASTER_MOD); #if 1 // full-duplex, interrupt should be enabled rx_flag = 1; spi_write(SPI_TEST_PORT, txbuffer, 8, spi_tx_cb); spi_read(SPI_TEST_PORT, rxbuffer, 8, spi_rx_cb); spi_int_enable(SPI_TEST_PORT, SPI_TX_INT|SPI_RX_INT, MASK_ENABLE); while(rx_flag); #else // half-duplex //Write 8byte data tx_flag = 1; spi_write(SPI_TEST_PORT, txbuffer, 8, spi_tx_cb); spi_int_enable(SPI_TEST_PORT, SPI_TX_INT, MASK_ENABLE); while(tx_flag); // wait for slave ready delay(100); //Read 8byte data rx_flag = 1; spi_read(SPI_TEST_PORT, rxbuffer, 8, spi_rx_cb); spi_int_enable(SPI_TEST_PORT, SPI_RX_INT, MASK_ENABLE); while(rx_flag); #endif #else //Initialize SPI spi_init(SPI_TEST_PORT, SPI_BITRATE(1000000), SPI_8BIT, SPI_SLAVE_MOD); tx_flag = 1; spi_read(SPI_TEST_PORT, rxbuffer, 8, spi_rx_cb); spi_write(SPI_TEST_PORT, txbuffer, 8, spi_tx_cb); spi_int_enable(SPI_TEST_PORT, SPI_TX_INT|SPI_RX_INT, MASK_ENABLE); while(tx_flag); #endif spi_clock_off(SPI_TEST_PORT); while (1) /* Loop forever */ { } }