/*
 * Copyright 2017-2020 NXP
 * This software is owned or controlled by NXP and may only be used strictly
 * in accordance with the applicable license terms.  By expressly accepting
 * such terms or by downloading, installing, activating and/or otherwise using
 * the software, you are agreeing that you have read, and that you agree to
 * comply with and are bound by, such license terms.  If you do not agree to
 * be bound by the applicable license terms, then you may not retain, install,
 * activate or otherwise use the software.
 */

/**
 * @defgroup KL_MODULES_AudioStreaming audio_DMA
 * @ingroup KL_MODULES_AudioStreaming
 * dma_interface is an abstraction layer for the DMA driver.
 * DMA registers and memory banks are accessed here.
 * This is a sub module of @ref KL_MODULES_AudioStreaming audio
 * @{
 */
/* ---------------------------------------------------------------------------- */
/* Include files                                                                */
/* ---------------------------------------------------------------------------- */
#include "fsl_dma.h"
#include "fsl_dmamux.h"
#include "dma_interface.h"
#include "audio_internal.h"

/**
 * Function to configure DMA as Tx or Rx
 */
void dma_ConfigureDMA(dma_handle_t *handle, uint8_t DmaChannel, uint32_t source)
{
    /* Enable DMA Mux for Channel 0 and select I2S Tx/Rx as source */
    DMAMUX_Init(AUDIO_SERVICE_DMAMUX_BASE);

    DMAMUX_SetSource(AUDIO_SERVICE_DMAMUX_BASE, DmaChannel, source);

    DMAMUX_EnableChannel(AUDIO_SERVICE_DMAMUX_BASE, DmaChannel);

    /* configure DMA */
    /* Set the channel, cycle steal, memory to peripheral and modulo for auto reset of circular buffer */
    DMA_Init(AUDIO_SERVICE_DMA_BASE);

    DMA_CreateHandle(handle, AUDIO_SERVICE_DMA_BASE, DmaChannel);
}

/**
 * Configure the Link Tx/Rx DMA
 */
void dma_ConfigureLinkDMA(dma_handle_t *handle, uint8_t DmaChannel, dma_callback callback)
{
    /* enable DMA Mux for Channel 0 and select I2S TX/RX as source */
    DMAMUX_Init(AUDIO_SERVICE_DMAMUX_BASE);

    DMAMUX_SetSource(AUDIO_SERVICE_DMAMUX_BASE, DmaChannel, DMAMUX_CHCFG_SOURCE_MASK);

    DMAMUX_EnableChannel(AUDIO_SERVICE_DMAMUX_BASE, DmaChannel);
    /* setup the link channel */
    DMA_CreateHandle(handle, AUDIO_SERVICE_DMA_BASE, DmaChannel);

    DMA_SetCallback(handle, callback, NULL);
}

/**
 * returns the address of source
 */
uint32_t dma_GetSourceAddress(DMA_Type *base, uint8_t channel)
{
    /* Gets the DMA Source address */
    return (uint32_t)base->DMA[channel].SAR;
}

/**
 * returns the address of Destination
 */
uint32_t dma_GetDestinationAddress(DMA_Type *base, uint8_t channel)
{
    /* Gets the DMA destination address */
    return (uint32_t)base->DMA[channel].DAR;
}

/**
 * Returns the BCR-Byte Count Register address
 */
uint32_t dma_GetBcrRegisterAddress(DMA_Type *base, uint8_t channel)
{
    /* Gets the DMA status register */
    return (uint32_t)&base->DMA[channel].DSR_BCR;
}

/**
 * Disables the DMA-Hardware request
 */
void dma_DisableHwRequest(DMA_Type *base, uint8_t channel, bool Status)
{
    if (Status == true) {
        base->DMA[channel].DCR |= DMA_DCR_D_REQ(true);
    } else {
        base->DMA[channel].DCR &= ~DMA_DCR_D_REQ_MASK;
    }
}
/** @} */
