void platform_wifi_spi_rx_dma_irq(void) { uint8_t junk1; uint16_t junk2; pdc_packet_t pdc_spi_packet = { 0, 1 }; Pdc* spi_pdc = spi_get_pdc_base( wifi_spi.port ); uint32_t status = spi_read_status( wifi_spi.port ); uint32_t mask = spi_read_interrupt_mask( wifi_spi.port ); if ( ( mask & SPI_IMR_RXBUFF ) && ( status & SPI_SR_RXBUFF ) ) { pdc_disable_transfer( spi_pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS ); pdc_rx_init( spi_pdc, &pdc_spi_packet, NULL ); pdc_tx_init( spi_pdc, &pdc_spi_packet, NULL ); spi_disable_interrupt( wifi_spi.port, SPI_IER_RXBUFF ); } if ( ( mask & SPI_IMR_ENDTX ) && ( status & SPI_SR_ENDTX ) ) { pdc_disable_transfer( spi_pdc, PERIPH_PTCR_TXTDIS ); pdc_tx_init( spi_pdc, &pdc_spi_packet, NULL ); spi_disable_interrupt( wifi_spi.port, SPI_IER_ENDTX ); /* Clear SPI RX data in a SPI send sequence */ spi_read( wifi_spi.port, &junk2, &junk1); } mico_rtos_set_semaphore( &spi_transfer_finished_semaphore ); }
/* * For internal use only. * A common SPI interrupt handler that is called for all SPI peripherals. */ static void local_spi_handler(const portBASE_TYPE spi_index) { portBASE_TYPE higher_priority_task_woken = pdFALSE; uint32_t spi_status; Spi *spi_port; spi_port = all_spi_definitions[spi_index].peripheral_base_address; spi_status = spi_read_status(spi_port); spi_status &= spi_read_interrupt_mask(spi_port); /* Has the PDC completed a transmission? */ if ((spi_status & SPI_SR_ENDTX) != 0UL) { spi_disable_interrupt(spi_port, SPI_IDR_ENDTX); /* If the driver is supporting multi-threading, then return the access mutex. */ if (tx_dma_control[spi_index].peripheral_access_mutex != NULL) { xSemaphoreGiveFromISR( tx_dma_control[spi_index].peripheral_access_mutex, &higher_priority_task_woken); } /* if the sending task supplied a notification semaphore, then * notify the task that the transmission has completed. */ if (tx_dma_control[spi_index].transaction_complete_notification_semaphore != NULL) { xSemaphoreGiveFromISR( tx_dma_control[spi_index].transaction_complete_notification_semaphore, &higher_priority_task_woken); } } /* Has the PDC completed a reception? */ if ((spi_status & SPI_SR_ENDRX) != 0UL) { spi_disable_interrupt(spi_port, SPI_IDR_ENDRX); /* If the driver is supporting multi-threading, then return the access mutex. NOTE: As a reception is performed by first performing a transmission, the SPI receive function uses the tx access semaphore. */ if (tx_dma_control[spi_index].peripheral_access_mutex != NULL) { xSemaphoreGiveFromISR( tx_dma_control[spi_index].peripheral_access_mutex, &higher_priority_task_woken); } /* If the receiving task supplied a notification semaphore, then notify the task that the transmission has completed. */ if (rx_dma_control[spi_index].transaction_complete_notification_semaphore != NULL) { xSemaphoreGiveFromISR( rx_dma_control[spi_index].transaction_complete_notification_semaphore, &higher_priority_task_woken); } } if ((spi_status & SR_ERROR_INTERRUPTS) != 0) { /* An mode error occurred in either a transmission or reception. Abort. Stop the transmission, disable interrupts used by the peripheral, and ensure the peripheral access mutex is made available to tasks. As this peripheral is half duplex, only the Tx peripheral access mutex exits. */ spi_disable_interrupt(spi_port, SPI_IDR_ENDTX); spi_disable_interrupt(spi_port, SPI_IDR_ENDRX); if (tx_dma_control[spi_index].peripheral_access_mutex != NULL) { xSemaphoreGiveFromISR( tx_dma_control[spi_index].peripheral_access_mutex, &higher_priority_task_woken); } /* The SPI port will have been disabled, re-enable it. */ spi_enable(spi_port); } /* If giving a semaphore caused a task to unblock, and the unblocked task has a priority equal to or higher than the currently running task (the task this ISR interrupted), then higher_priority_task_woken will have automatically been set to pdTRUE within the semaphore function. portEND_SWITCHING_ISR() will then ensure that this ISR returns directly to the higher priority unblocked task. */ portEND_SWITCHING_ISR(higher_priority_task_woken); }