void spi_master_transfer(spi_t *obj, void *tx, size_t tx_length, void *rx, size_t rx_length, uint32_t handler, uint32_t event, DMAUsage hint) { if (hint != DMA_USAGE_NEVER && obj->spi.dma_state == DMA_USAGE_ALLOCATED) { // setup dma done, activate } else if (hint == DMA_USAGE_NEVER) { obj->spi.dma_state = DMA_USAGE_NEVER; spi_enable_event_flags(obj, event, true); spi_buffer_set(obj, tx, tx_length, rx, rx_length); // Clear the FIFO DSPI_HAL_SetFlushFifoCmd(obj->spi.address,true,true); // Enable the FIFO DSPI_HAL_SetFifoCmd(obj->spi.address, true, true); // Start writing to the SPI peripheral spi_master_write_asynch(obj,SPI_ASYNCH_INITIAL_TX); // use IRQ spi_master_enable_interrupt(obj, true); spi_enable_vector_interrupt(obj, handler, true); } else { // setup and activate } }
void spi_master_transfer(spi_t *obj, const void *tx, size_t tx_length, void *rx, size_t rx_length, uint8_t bit_width, uint32_t handler, uint32_t event, DMAUsage hint) { if(spi_active(obj)) { return; } /* check corner case */ if(tx_length == 0) { tx_length = rx_length; tx = (void*) 0; } /* First, set the buffer */ spi_buffer_set(obj, tx, tx_length, rx, rx_length, bit_width); /* If using DMA, allocate channels only if they have not already been allocated */ if (hint != DMA_USAGE_NEVER) { /* User requested to transfer using DMA */ spi_enable_dma(obj, handler, hint); /* Check if DMA setup was successful */ if (obj->spi.spiDmaMasterRx.dmaUsageState != DMA_USAGE_ALLOCATED && obj->spi.spiDmaMasterRx.dmaUsageState != DMA_USAGE_TEMPORARY_ALLOCATED) { /* Set up an interrupt transfer as DMA is unavailable */ DSPI_MasterTransferCreateHandle(spi_address[obj->spi.instance], &obj->spi.spi_master_handle, (dspi_master_transfer_callback_t)handler, NULL); } } else { /* User requested to transfer using interrupts */ /* Disable the DMA */ spi_enable_dma(obj, handler, hint); /* Set up the interrupt transfer */ DSPI_MasterTransferCreateHandle(spi_address[obj->spi.instance], &obj->spi.spi_master_handle, (dspi_master_transfer_callback_t)handler, NULL); } /* Start the transfer */ if (spi_master_transfer_asynch(obj) != kStatus_Success) { obj->spi.status = kDSPI_Idle; } }