Beispiel #1
0
status_t SPIFI_TransferReceiveDMA(SPIFI_Type *base, spifi_dma_handle_t *handle, spifi_transfer_t *xfer)
{
    assert(handle && (handle->dmaHandle));

    dma_transfer_config_t xferConfig;
    status_t status;

    /* If previous TX not finished. */
    if (kSPIFI_BusBusy == handle->state)
    {
        status = kStatus_SPIFI_Busy;
    }
    else
    {
        handle->state = kSPIFI_BusBusy;

        /* Prepare transfer. */
        DMA_PrepareTransfer(&xferConfig, (void *)SPIFI_GetDataRegisterAddress(base), xfer->data, sizeof(uint32_t),
                            xfer->dataSize, kDMA_PeripheralToMemory, NULL);

        /* Submit transfer. */
        DMA_SubmitTransfer(handle->dmaHandle, &xferConfig);
        DMA_StartTransfer(handle->dmaHandle);

        /* Enable SPIFI TX DMA. */
        SPIFI_EnableDMA(base, true);

        status = kStatus_Success;
    }

    return status;
}
Beispiel #2
0
static void I2C_MasterTransferDMAConfig(I2C_Type *base, i2c_master_dma_handle_t *handle)
{
    dma_transfer_config_t transfer_config;
    dma_transfer_options_t transfer_options = kDMA_EnableInterrupt;

    if (handle->transfer.direction == kI2C_Read)
    {
        transfer_config.srcAddr = (uint32_t)I2C_GetDataRegAddr(base);
        transfer_config.destAddr = (uint32_t)(handle->transfer.data);
        transfer_config.transferSize = (handle->transfer.dataSize - 1);
        transfer_config.srcSize = kDMA_Transfersize8bits;
        transfer_config.enableSrcIncrement = false;
        transfer_config.destSize = kDMA_Transfersize8bits;
        transfer_config.enableDestIncrement = true;
    }
    else
    {
        transfer_config.srcAddr = (uint32_t)(handle->transfer.data + 1);
        transfer_config.destAddr = (uint32_t)I2C_GetDataRegAddr(base);
        transfer_config.transferSize = (handle->transfer.dataSize - 1);
        transfer_config.srcSize = kDMA_Transfersize8bits;
        transfer_config.enableSrcIncrement = true;
        transfer_config.destSize = kDMA_Transfersize8bits;
        transfer_config.enableDestIncrement = false;
    }

    DMA_SubmitTransfer(handle->dmaHandle, &transfer_config, transfer_options);
    DMA_StartTransfer(handle->dmaHandle);
}
Beispiel #3
0
status_t USART_TransferReceiveDMA(USART_Type *base, usart_dma_handle_t *handle, usart_transfer_t *xfer)
{
    assert(handle);
    assert(handle->rxDmaHandle);
    assert(xfer);
    assert(xfer->data);
    assert(xfer->dataSize);

    dma_transfer_config_t xferConfig;
    status_t status;

    /* If previous RX not finished. */
    if (kUSART_RxBusy == handle->rxState)
    {
        status = kStatus_USART_RxBusy;
    }
    else
    {
        handle->rxState = kUSART_RxBusy;
        handle->rxDataSizeAll = xfer->dataSize;

        /* Enable DMA request from rxFIFO */
        USART_EnableRxDMA(base, true);

        /* Prepare transfer. */
        DMA_PrepareTransfer(&xferConfig, (void *)&base->FIFORD, xfer->data, sizeof(uint8_t), xfer->dataSize,
                            kDMA_PeripheralToMemory, NULL);

        /* Submit transfer. */
        DMA_SubmitTransfer(handle->rxDmaHandle, &xferConfig);
        DMA_StartTransfer(handle->rxDmaHandle);

        status = kStatus_Success;
    }

    return status;
}
status_t UART_TransferReceiveDMA(UART_Type *base, uart_dma_handle_t *handle, uart_transfer_t *xfer)
{
    assert(handle);
    assert(handle->rxDmaHandle);
    assert(xfer);
    assert(xfer->data);
    assert(xfer->dataSize);

    dma_transfer_config_t xferConfig;
    status_t status;

    /* If previous RX not finished. */
    if (kUART_RxBusy == handle->rxState)
    {
        status = kStatus_UART_RxBusy;
    }
    else
    {
        handle->rxState = kUART_RxBusy;
        handle->rxDataSizeAll = xfer->dataSize;

        /* Prepare transfer. */
        DMA_PrepareTransfer(&xferConfig, (void *)UART_GetDataRegisterAddress(base), sizeof(uint8_t), xfer->data,
                            sizeof(uint8_t), xfer->dataSize, kDMA_PeripheralToMemory);

        /* Submit transfer. */
        DMA_SubmitTransfer(handle->rxDmaHandle, &xferConfig, kDMA_EnableInterrupt);
        DMA_StartTransfer(handle->rxDmaHandle);

        /* Enable UART RX DMA. */
        UART_EnableRxDMA(base, true);

        status = kStatus_Success;
    }

    return status;
}
status_t SPI_MasterTransferDMA(SPI_Type *base, spi_dma_handle_t *handle, spi_transfer_t *xfer)
{
    assert(handle && xfer);

    dma_transfer_config_t config = {0};

    /* Check if the device is busy */
    if (handle->state == kSPI_Busy)
    {
        return kStatus_SPI_Busy;
    }

    /* Check if input parameter invalid */
    if (((xfer->txData == NULL) && (xfer->rxData == NULL)) || (xfer->dataSize == 0U))
    {
        return kStatus_InvalidArgument;
    }
    
    /* Disable SPI and then enable it, this is used to clear S register*/
    SPI_Enable(base, false);
    SPI_Enable(base, true);
    
    /* Configure tx transfer DMA */
    config.destAddr = SPI_GetDataRegisterAddress(base);
    config.enableDestIncrement = false;
    if (handle->bytesPerFrame == 1U)
    {
        config.srcSize = kDMA_Transfersize8bits;
        config.destSize = kDMA_Transfersize8bits;
    }
    else
    {
        config.srcSize = kDMA_Transfersize16bits;
        config.destSize = kDMA_Transfersize16bits;
    }
    config.transferSize = xfer->dataSize;
    /* Configure DMA channel */
    if (xfer->txData)
    {
        config.enableSrcIncrement = true;
        config.srcAddr = (uint32_t)(xfer->txData);
    }
    else
    {
        /* Disable the source increasement and source set to dummyData */
        config.enableSrcIncrement = false;
        config.srcAddr = (uint32_t)(&s_dummyData);
    }
    DMA_SubmitTransfer(handle->txHandle, &config, true);

    /* Handle rx transfer */
    if (xfer->rxData)
    {
        /* Set the source address */
        DMA_SetDestinationAddress(handle->rxHandle->base, handle->rxHandle->channel, (uint32_t)(xfer->rxData));

        /* Set the transfer size */
        DMA_SetTransferSize(handle->rxHandle->base, handle->rxHandle->channel, xfer->dataSize);
    }

    /* Change the state of handle */
    handle->transferSize = xfer->dataSize;
    handle->state = kSPI_Busy;

    /* Start Rx transfer if needed */
    if (xfer->rxData)
    {
        handle->rxInProgress = true;
        SPI_EnableDMA(base, kSPI_RxDmaEnable, true);
        DMA_StartTransfer(handle->rxHandle);
    }

    /* Always start Tx transfer */
    handle->txInProgress = true;
    SPI_EnableDMA(base, kSPI_TxDmaEnable, true);
    DMA_StartTransfer(handle->txHandle);

    return kStatus_Success;
}
void SPI_MasterTransferCreateHandleDMA(SPI_Type *base,
                                       spi_dma_handle_t *handle,
                                       spi_dma_callback_t callback,
                                       void *userData,
                                       dma_handle_t *txHandle,
                                       dma_handle_t *rxHandle)
{
    assert(handle);
    dma_transfer_config_t config = {0};
    uint32_t instance = SPI_GetInstance(base);

    /* Set spi base to handle */
    handle->txHandle = txHandle;
    handle->rxHandle = rxHandle;
    handle->callback = callback;
    handle->userData = userData;

    /* Set SPI state to idle */
    handle->state = kSPI_Idle;

    /* Set handle to global state */
    s_dmaPrivateHandle[instance].base = base;
    s_dmaPrivateHandle[instance].handle = handle;

/* Compute internal state */
#if defined(FSL_FEATURE_SPI_16BIT_TRANSFERS) && (FSL_FEATURE_SPI_16BIT_TRANSFERS)
    handle->bytesPerFrame = ((base->C2 & SPI_C2_SPIMODE_MASK) >> SPI_C2_SPIMODE_SHIFT) + 1U;
#else
    handle->bytesPerFrame = 1U;
#endif /* FSL_FEATURE_SPI_16BIT_TRANSFERS */

#if defined(FSL_FEATURE_SPI_HAS_FIFO) && (FSL_FEATURE_SPI_HAS_FIFO)
    /* If using DMA, disable FIFO, as the FIFO may cause data loss if the data size is not integer
       times of 2bytes. As SPI cannot set watermark to 0, only can set to 1/2 FIFO size or 3/4 FIFO
       size. */
    if (FSL_FEATURE_SPI_FIFO_SIZEn(base) != 0)
    {
        base->C3 &= ~SPI_C3_FIFOMODE_MASK;
    }

#endif /* FSL_FEATURE_SPI_HAS_FIFO */

    /* Set the non-change attribute for Tx DMA transfer, to improve efficiency */
    config.destAddr = SPI_GetDataRegisterAddress(base);
    config.enableDestIncrement = false;
    config.enableSrcIncrement = true;
    if (handle->bytesPerFrame == 1U)
    {
        config.srcSize = kDMA_Transfersize8bits;
        config.destSize = kDMA_Transfersize8bits;
    }
    else
    {
        config.srcSize = kDMA_Transfersize16bits;
        config.destSize = kDMA_Transfersize16bits;
    }

    DMA_SubmitTransfer(handle->txHandle, &config, true);

    /* Set non-change attribute for Rx DMA */
    config.srcAddr = SPI_GetDataRegisterAddress(base);
    config.destAddr = 0U;
    config.enableDestIncrement = true;
    config.enableSrcIncrement = false;
    DMA_SubmitTransfer(handle->rxHandle, &config, true);

    /* Install callback for Tx dma channel */
    DMA_SetCallback(handle->txHandle, SPI_TxDMACallback, &s_dmaPrivateHandle[instance]);
    DMA_SetCallback(handle->rxHandle, SPI_RxDMACallback, &s_dmaPrivateHandle[instance]);
}