/*******************************************************************************
* DISCLAIMER
* This software is supplied by Renesas Electronics Corporation and is only
* intended for use with Renesas products. No other uses are authorized. This
* software is owned by Renesas Electronics Corporation and is protected under
* all applicable laws, including copyright laws.
* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT
* LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.
* TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS
* ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE
* FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR
* ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE
* BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* Renesas reserves the right, without notice, to make changes to this software
* and to discontinue the availability of this software. By using this software,
* you agree to the additional terms and conditions found by accessing the
* following link:
* http://www.renesas.com/disclaimer *
* Copyright (C) 2014 Renesas Electronics Corporation
* and Renesas Solutions Corp. All rights reserved.
*******************************************************************************/
/*******************************************************************************
* File Name    : r_dmac_apl.c
* Version      : 1.00
* Device(s)    : Renesas
* Tool-Chain   : Renesas
* OS           : None
* H/W Platform : Independent
* Description  : This is DMAC application program code.
******************************************************************************/
/*****************************************************************************
* History : DD.MM.YYYY Version Description
*         : 01.09.2014 1.00    First Release
******************************************************************************/

/******************************************************************************
Includes <System Includes> , "Project Includes"
******************************************************************************/
#include    "platform.h"
#include    "r_dmaca_rx_if.h"
#include    "r_pdc_rx_if.h"
#include    "r_pdc_apl.h"
#include "r_jpeg_enc_apl.h"

#define     DMAC_INITIAL
#include    "r_dmac_apl.h"

/******************************************************************************
Macro definitions
******************************************************************************/

/******************************************************************************
Typedef definitions
******************************************************************************/

/******************************************************************************
Exported global variables and functions (to be accessed by other files)
******************************************************************************/
extern uint8_t buf_jpeg[];
extern uint8_t buf_image[];

/******************************************************************************
Private global variables and functions
******************************************************************************/
static dmaca_transfer_data_cfg_t    g_data_dmac_ch0;
static dmaca_transfer_data_cfg_t    g_data_dmac_ch1;

static void dmac0_end_int( void );
static void dmac1_end_int( void );

/******************************************************************************
Exported global variables and functions (to be accessed by other files)
******************************************************************************/
extern uint8_t buf_jpeg[];
extern uint8_t buf_image[];

/***********************************************************************************************************************
* Function Name: R_dmac_init
* Description  : DMAC module initialize
* Arguments    : none
* Return Value : none
***********************************************************************************************************************/
void R_dmac_init( void )
{
    R_DMACA_Init();
}

/***********************************************************************************************************************
* Function Name: R_dmac_ch0_init
* Description  : dmac ch0 initialize
* Arguments    : unsigned char continue_flag:forwarding address initial flag(0:initialize,1:continue)
* Return Value : none
***********************************************************************************************************************/
void R_dmac_ch0_init( uint8_t continue_flag )
{
    volatile dmaca_return_t      ret_dmac;
    dmaca_stat_t                 stat_dmac;

    g_data_dmac_ch0.des_addr_mode        = DMACA_DES_ADDR_INCR;
    g_data_dmac_ch0.src_addr_mode        = DMACA_SRC_ADDR_FIXED;
    g_data_dmac_ch0.des_addr_repeat_area = DMACA_DES_ADDR_EXT_REP_AREA_NONE;
    g_data_dmac_ch0.src_addr_repeat_area = DMACA_SRC_ADDR_EXT_REP_AREA_NONE;
    g_data_dmac_ch0.transfer_mode        = DMACA_TRANSFER_MODE_BLOCK;
    g_data_dmac_ch0.repeat_block_side    = DMACA_REPEAT_BLOCK_SOURCE;
    g_data_dmac_ch0.data_size            = DMACA_DATA_SIZE_LWORD;
    g_data_dmac_ch0.request_source       = DMACA_TRANSFER_REQUEST_PERIPHERAL;
    g_data_dmac_ch0.block_size           = 0x0008;
    g_data_dmac_ch0.transfer_count       = 0x0280;
    g_data_dmac_ch0.p_src_addr           = R_PDC_GetFifoAddr();
    g_data_dmac_ch0.p_des_addr           = (void *)((uint32_t)R_get_pdc_capture_buf_adr() + (continue_flag * ((g_pdc_size_width * 2) * g_pdc_size_height)));
    g_data_dmac_ch0.offset_value         = 0x00000001;
    g_data_dmac_ch0.dtie_request         = DMACA_TRANSFER_END_INTERRUPT_ENABLE;
    g_data_dmac_ch0.esie_request         = DMACA_TRANSFER_ESCAPE_END_INTERRUPT_DISABLE;
    g_data_dmac_ch0.rptie_request        = DMACA_REPEAT_SIZE_END_INTERRUPT_DISABLE;
    g_data_dmac_ch0.sarie_request        = DMACA_SRC_ADDR_EXT_REP_AREA_OVER_INTERRUPT_DISABLE;
    g_data_dmac_ch0.darie_request        = DMACA_DES_ADDR_EXT_REP_AREA_OVER_INTERRUPT_DISABLE;
    g_data_dmac_ch0.act_source           = IR_PDC_PCDFI;
    g_data_dmac_ch0.interrupt_sel        = DMACA_CLEAR_INTERRUPT_FLAG_BEGINNING_TRANSFER;

    ret_dmac = R_DMACA_Create(DMACA_CH0, &g_data_dmac_ch0);
    if (DMACA_SUCCESS != ret_dmac)
    {
        /* do something */
    }

    ret_dmac = R_DMACA_Int_Callback(DMACA_CH0, dmac0_end_int);
    if (DMACA_SUCCESS != ret_dmac)
    {
        /* do something */
    }
    ret_dmac = R_DMACA_Int_Enable(DMACA_CH0, 8);
    if (DMACA_SUCCESS != ret_dmac)
    {
        /* do something */
    }
    ret_dmac = R_DMACA_Control(DMACA_CH0, DMACA_CMD_ENABLE, &stat_dmac);
    if (DMACA_SUCCESS != ret_dmac)
    {
        /* do something */
    }
}

/***********************************************************************************************************************
* Function Name: R_dmac_ch1_init
* Description  : dmac ch1 initialize
* Arguments    : unsigned char continue_flag:forwarding address initial flag(0:initialize,1:continue)
* Return Value : none
***********************************************************************************************************************/
void R_dmac_ch1_init( uint8_t continue_flag )
{
    volatile dmaca_return_t      ret_dmac;
    dmaca_stat_t                 stat_dmac;

    g_data_dmac_ch1.des_addr_mode        = DMACA_DES_ADDR_INCR;
    g_data_dmac_ch1.src_addr_mode        = DMACA_SRC_ADDR_INCR;
    g_data_dmac_ch1.des_addr_repeat_area = DMACA_DES_ADDR_EXT_REP_AREA_NONE;
    g_data_dmac_ch1.src_addr_repeat_area = DMACA_SRC_ADDR_EXT_REP_AREA_NONE;
    g_data_dmac_ch1.transfer_mode        = DMACA_TRANSFER_MODE_BLOCK;
    g_data_dmac_ch1.repeat_block_side    = DMACA_REPEAT_BLOCK_DISABLE;
    g_data_dmac_ch1.data_size            = DMACA_DATA_SIZE_LWORD;
    g_data_dmac_ch1.request_source       = DMACA_TRANSFER_REQUEST_SOFTWARE;//DMACA_TRANSFER_REQUEST_PERIPHERAL;
    g_data_dmac_ch1.block_size           = JPEG_OUTPUT_AREA_SIZE / 1024; // 1K=1024byte
    g_data_dmac_ch1.transfer_count       = (1024 / 4);                   // DMACA_DATA_SIZE_LWORD = 32bit
    g_data_dmac_ch1.p_src_addr           = (void *)buf_jpeg;
    g_data_dmac_ch1.p_des_addr           = (void *)buf_image;
    g_data_dmac_ch1.offset_value         = 0x00000000;
    g_data_dmac_ch1.dtie_request         = DMACA_TRANSFER_END_INTERRUPT_ENABLE;
    g_data_dmac_ch1.esie_request         = DMACA_TRANSFER_ESCAPE_END_INTERRUPT_DISABLE;
    g_data_dmac_ch1.rptie_request        = DMACA_REPEAT_SIZE_END_INTERRUPT_DISABLE;
    g_data_dmac_ch1.sarie_request        = DMACA_SRC_ADDR_EXT_REP_AREA_OVER_INTERRUPT_DISABLE;
    g_data_dmac_ch1.darie_request        = DMACA_DES_ADDR_EXT_REP_AREA_OVER_INTERRUPT_DISABLE;
    g_data_dmac_ch1.act_source           = IR_DMAC_DMAC1I;
    g_data_dmac_ch1.interrupt_sel        = DMACA_CLEAR_INTERRUPT_FLAG_BEGINNING_TRANSFER;

    ret_dmac = R_DMACA_Create(DMACA_CH1, &g_data_dmac_ch1);
    if (DMACA_SUCCESS != ret_dmac)
    {
        /* do something */
    }

    ret_dmac = R_DMACA_Int_Callback(DMACA_CH1, dmac1_end_int);
    if (DMACA_SUCCESS != ret_dmac)
    {
        /* do something */
    }

    ret_dmac = R_DMACA_Int_Enable(DMACA_CH1, 8);
    if (DMACA_SUCCESS != ret_dmac)
    {
        /* do something */
    }

    ret_dmac = R_DMACA_Control(DMACA_CH1, DMACA_CMD_ENABLE, &stat_dmac);
    if (DMACA_SUCCESS != ret_dmac)
    {
        /* do something */
    }

    ret_dmac = R_DMACA_Control(DMACA_CH1, DMACA_CMD_SOFT_REQ_NOT_CLR_REQ, &stat_dmac);
    if (DMACA_SUCCESS != ret_dmac)
    {
        /* do something */
    }

}

/***********************************************************************************************************************
* Function Name: dmac0_end_int
* Description  : This function is a callback function when DMAC finishes transmission.
* Arguments    : none
* Return Value : none
***********************************************************************************************************************/
static void dmac0_end_int( void )
{
    volatile dmaca_return_t      ret_dmac;
    dmaca_stat_t                 stat_dmac;
    uint32_t                     dest_adr;

    ret_dmac = R_DMACA_Control(DMACA_CH0, DMACA_CMD_STATUS_GET, &stat_dmac);
    if (DMACA_SUCCESS != ret_dmac)
    {
        /* do something */
    }
    /* One block size added destination address. */
    dest_adr = (uint32_t)(g_data_dmac_ch0.p_des_addr);
    dest_adr += (4 * g_data_dmac_ch0.block_size * g_data_dmac_ch0.transfer_count);
    g_data_dmac_ch0.p_des_addr = (void *)dest_adr;
    /* Update destination address and block transfer count. */
    ret_dmac = R_DMACA_Create(DMACA_CH0, &g_data_dmac_ch0);
    if (DMACA_SUCCESS != ret_dmac)
    {
        /* do something */
    }
    /* status clear of DMAC */
    if (true == (stat_dmac.dtif_stat))
    {
        ret_dmac = R_DMACA_Control(DMACA_CH0, DMACA_CMD_DTIF_STATUS_CLR, &stat_dmac);
        if (DMACA_SUCCESS != ret_dmac)
        {
            /* do something */
        }
    }
    if (true == (stat_dmac.esif_stat))
    {
        ret_dmac = R_DMACA_Control(DMACA_CH0, DMACA_CMD_ESIF_STATUS_CLR, &stat_dmac);
    }
    ret_dmac = R_DMACA_Control(DMACA_CH0, DMACA_CMD_ENABLE, &stat_dmac);
    if (DMACA_SUCCESS != ret_dmac)
    {
        /* do something */
    }
}

/***********************************************************************************************************************
* Function Name: dmac1_end_int
* Description  : This function is a callback function when DMAC finishes transmission.
* Arguments    : none
* Return Value : none
***********************************************************************************************************************/
static void dmac1_end_int( void )
{
    volatile dmaca_return_t      ret_dmac;
    dmaca_stat_t                 stat_dmac;

    ret_dmac = R_DMACA_Control(DMACA_CH1, DMACA_CMD_STATUS_GET, &stat_dmac);
    if (DMACA_SUCCESS != ret_dmac)
    {
        /* do something */
    }

    ret_dmac = R_DMACA_Create(DMACA_CH1, &g_data_dmac_ch1);
    if (DMACA_SUCCESS != ret_dmac)
    {
        /* do something */
    }

    /* status clear of DMAC */
    if (true == (stat_dmac.dtif_stat))
    {
        ret_dmac = R_DMACA_Control(DMACA_CH1, DMACA_CMD_DTIF_STATUS_CLR, &stat_dmac);
        if (DMACA_SUCCESS != ret_dmac)
        {
            /* do something */
        }
    }
    if (true == (stat_dmac.esif_stat))
    {
        ret_dmac = R_DMACA_Control(DMACA_CH1, DMACA_CMD_ESIF_STATUS_CLR, &stat_dmac);
    }

    ret_dmac = R_DMACA_Control(DMACA_CH1, DMACA_CMD_ENABLE, &stat_dmac);
    if (DMACA_SUCCESS != ret_dmac)
    {
        /* do something */
    }

}

/******************************************************************************
End of file
******************************************************************************/
