/// Processing done after rx completes. void process_rx_dma_interrupt(struct spi_periph *periph) { struct spi_periph_dma *dma = periph->init_struct; struct spi_transaction *trans = periph->trans[periph->trans_extract_idx]; /* Disable DMA Channel */ dma_disable_transfer_complete_interrupt(dma->dma, dma->rx_chan); /* Disable SPI Rx request */ spi_disable_rx_dma((uint32_t)periph->reg_addr); /* Disable DMA rx channel */ dma_disable_channel(dma->dma, dma->rx_chan); if (dma->rx_extra_dummy_dma) { /* * We are finished the first part of the receive with real data, * but still need to run the dummy to get a transfer complete interrupt * after the complete transaction is done. */ /* Reset the flag so this only happens once in a transaction */ dma->rx_extra_dummy_dma = FALSE; /* Use the difference in length between rx and tx */ uint16_t len_remaining = trans->output_length - trans->input_length; spi_configure_dma(dma->dma, dma->rx_chan, (uint32_t)dma->spidr, (uint32_t)&(dma->rx_dummy_buf), len_remaining, trans->dss, FALSE); dma_set_read_from_peripheral(dma->dma, dma->rx_chan); dma_set_priority(dma->dma, dma->rx_chan, DMA_CCR_PL_HIGH); /* Enable DMA transfer complete interrupts. */ dma_enable_transfer_complete_interrupt(dma->dma, dma->rx_chan); /* Enable DMA channels */ dma_enable_channel(dma->dma, dma->rx_chan); /* Enable SPI transfers via DMA */ spi_enable_rx_dma((uint32_t)periph->reg_addr); } else { /* * Since the receive DMA is always run until the very end * and this interrupt is triggered after the last data word was read, * we now know that this transaction is finished. */ /* Run the callback */ trans->status = SPITransSuccess; if (trans->after_cb != 0) { trans->after_cb(trans); } /* AFTER the callback, then unselect the slave if required */ if (trans->select == SPISelectUnselect || trans->select == SPIUnselect) { SpiSlaveUnselect(trans->slave_idx); } spi_next_transaction(periph); } }
/* RX IRQ */ void dma1_stream3_isr(void) { // d_print("RX ISR: %lu:%lu\r\n", DMA1_LISR, DMA1_HISR); dma_disable_transfer_complete_interrupt(DMA1, DMA_STREAM3); dma_disable_stream(DMA1, DMA_STREAM3); rxcomplete = 1; }
// DMA1_CHANNEL2 UART3_TX void dma1_channel2_isr(void) { if ((DMA1_ISR & DMA_ISR_TCIF2) != 0) { DMA1_IFCR |= DMA_IFCR_CTCIF2; dma_disable_transfer_complete_interrupt(DMA1, DMA_CHANNEL2); usart_disable_tx_dma(USART3); dma_disable_channel(DMA1, DMA_CHANNEL2); (*tx_done_handler)(); } }
void _USART_DMA_ISR(void) { DMA_IFCR(_USART_DMA) |= DMA_IFCR_CTCIF(_USART_DMA_CHANNEL); dma_disable_transfer_complete_interrupt(_USART_DMA, _USART_DMA_CHANNEL); usart_disable_tx_dma(_USART); dma_disable_channel(_USART_DMA, _USART_DMA_CHANNEL); busy = 0; }
void acq_pause() { gpio_clear(BANK_LED, GPIO_LED); spi_disable(SPI_C1); spi_disable_rx_dma(SPI_C1); dma_disable_transfer_complete_interrupt(DMA1, DMA_CHANNEL2); dma_disable_half_transfer_interrupt(DMA1, DMA_CHANNEL2); dma_disable_channel(DMA1, DMA_CHANNEL2); nvic_disable_irq(NVIC_DMA1_CHANNEL2_IRQ); }
// DMA1_CHANNEL2 UART3_RX void dma1_channel3_isr(void){ if ((DMA1_ISR & DMA_ISR_TCIF3) != 0) { DMA1_IFCR |= DMA_IFCR_CTCIF3; dma_disable_transfer_complete_interrupt(DMA1, DMA_CHANNEL3); usart_disable_rx_dma(USART3); dma_disable_channel(DMA1, DMA_CHANNEL3); gpio_set(GPIOB, GPIO_DEBUG_1); // hal_uart_manual_rts_set(); (*rx_done_handler)(); } }
/* SPI receive completed with DMA */ void dma1_channel2_isr(void) { gpio_set(GPIOA,GPIO4); if ((DMA1_ISR &DMA_ISR_TCIF2) != 0) { DMA1_IFCR |= DMA_IFCR_CTCIF2; } dma_disable_transfer_complete_interrupt(DMA1, DMA_CHANNEL2); spi_disable_rx_dma(SPI1); dma_disable_channel(DMA1, DMA_CHANNEL2); /* Increment the status to indicate one of the transfers is complete */ transceive_status++; gpio_clear(GPIOA,GPIO4); }
/* SPI transmit completed with DMA */ void dma1_channel3_isr(void) { gpio_set(GPIOB,GPIO1); if ((DMA1_ISR &DMA_ISR_TCIF3) != 0) { DMA1_IFCR |= DMA_IFCR_CTCIF3; } dma_disable_transfer_complete_interrupt(DMA1, DMA_CHANNEL3); spi_disable_tx_dma(SPI1); dma_disable_channel(DMA1, DMA_CHANNEL3); /* If tx_len < rx_len, create a dummy transfer to clock in the remaining * rx data */ if (rx_buf_remainder > 0) { dma_channel_reset(DMA1, DMA_CHANNEL3); dma_set_peripheral_address(DMA1, DMA_CHANNEL3, (uint32_t)&SPI1_DR); dma_set_memory_address(DMA1, DMA_CHANNEL3, (uint32_t)(&dummy_tx_buf)); // Change here dma_set_number_of_data(DMA1, DMA_CHANNEL3, rx_buf_remainder); // Change here dma_set_read_from_memory(DMA1, DMA_CHANNEL3); dma_disable_memory_increment_mode(DMA1, DMA_CHANNEL3); // Change here #if USE_16BIT_TRANSFERS dma_set_peripheral_size(DMA1, DMA_CHANNEL3, DMA_CCR_PSIZE_16BIT); dma_set_memory_size(DMA1, DMA_CHANNEL3, DMA_CCR_MSIZE_16BIT); #else dma_set_peripheral_size(DMA1, DMA_CHANNEL3, DMA_CCR_PSIZE_8BIT); dma_set_memory_size(DMA1, DMA_CHANNEL3, DMA_CCR_MSIZE_8BIT); #endif dma_set_priority(DMA1, DMA_CHANNEL3, DMA_CCR_PL_HIGH); rx_buf_remainder = 0; // Clear the buffer remainder to disable this section later dma_enable_transfer_complete_interrupt(DMA1, DMA_CHANNEL3); dma_enable_channel(DMA1, DMA_CHANNEL3); spi_enable_tx_dma(SPI1); } else { /* Increment the status to indicate one of the transfers is complete */ transceive_status++; } gpio_clear(GPIOB,GPIO1); }
/// Processing done after tx completes void process_tx_dma_interrupt(struct spi_periph *periph) { struct spi_periph_dma *dma = periph->init_struct; struct spi_transaction *trans = periph->trans[periph->trans_extract_idx]; /* Disable DMA Channel */ dma_disable_transfer_complete_interrupt(dma->dma, dma->tx_chan); /* Disable SPI TX request */ spi_disable_tx_dma((uint32_t)periph->reg_addr); /* Disable DMA tx channel */ dma_disable_channel(dma->dma, dma->tx_chan); if (dma->tx_extra_dummy_dma) { /* * We are finished the first part of the transmit with real data, * but still need to clock in the rest of the receive data. * Set up a dummy dma transmit transfer to accomplish this. */ /* Reset the flag so this only happens once in a transaction */ dma->tx_extra_dummy_dma = FALSE; /* Use the difference in length between tx and rx */ uint16_t len_remaining = trans->input_length - trans->output_length; spi_configure_dma(dma->dma, dma->tx_chan, (uint32_t)dma->spidr, (uint32_t)&(dma->tx_dummy_buf), len_remaining, trans->dss, FALSE); dma_set_read_from_memory(dma->dma, dma->tx_chan); dma_set_priority(dma->dma, dma->tx_chan, DMA_CCR_PL_MEDIUM); /* Enable DMA transfer complete interrupts. */ dma_enable_transfer_complete_interrupt(dma->dma, dma->tx_chan); /* Enable DMA channels */ dma_enable_channel(dma->dma, dma->tx_chan); /* Enable SPI transfers via DMA */ spi_enable_tx_dma((uint32_t)periph->reg_addr); } }