Beispiel #1
0
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 );
}
Beispiel #2
0
/*
 * 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);
}