/**
  ******************************************************************************
 *
 * @file        Sample_MID_DAC_DMA_PeriodOutput.c
 *
 * @brief       DAC initial with period trigger and DMA access.
 *
 * @par         Project
 *              MG32
 * @version     V1.14
 * @date        2023/03/29
 * @author      Megawin Software Center
 * @copyright   Copyright (c) 2017 MegaWin Technology Co., Ltd.
 *              All rights reserved.
 *
 ******************************************************************************
* @par Disclaimer
 * The Demo software is provided "AS IS" without any warranty, either
 * expressed or implied, including, but not limited to, the implied warranties
 * of merchantability and fitness for a particular purpose. The author will
 * not be liable for any special, incidental, consequential or indirect
 * damages due to loss of data or any other reason.
 * These statements agree with the world wide and local dictated laws about
 * authorship and violence against these laws.
 *******************************************************************************
 ******************************************************************************
 */


/* Includes ------------------------------------------------------------------*/
#include "MG32_TM_MID.h"
#include "MG32_DAC_MID.h"

/* Wizard menu ---------------------------------------------------------------*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
static TM_HandleTypeDef mTM10;
static DAC_HandleTypeDef mDAC;
static DMA_HandleTypeDef mDMA;

static uint16_t DAC_DMA_Pattern[] = { 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000};

/* Private function prototypes -----------------------------------------------*/
void Sample_MID_DAC_DMA_PeriodOutput(void);

/* Exported variables --------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
/* External vairables --------------------------------------------------------*/

/*
 *******************************************************************************
 * @brief	    DAC initial with period trigger and DMA access.
 * @details     1. Initial TM10 timer : counter range is 300*65536 clocks.
 *    \n        2. Initial TM10 clock mode.
 *    \n        3. Initial TM10 TRGO configuration.
 *    \n        4. Start TM10.
 *    \n        5. Initial DAC.
 *    \n        6. Initial DMA.
 *    \n        7. Start DAC /w DMA. 
 * @return      None
 *******************************************************************************
 */
void Sample_MID_DAC_DMA_PeriodOutput(void)
{  
    TM_ClockConfigTypeDef   CKConfig;
    TM_MasterConfigTypeDef  TM_TRGOConfig;

    
    // make sure :
    
    //===Set CSC init====
    //MG32_CSC_Init.h(Configuration Wizard)
    //Select CK_HS source = CK_IHRCO
    //Select IHRCO = 12M
    //  Select CK_PLLI Divider = CK_HS/2
    //  Select CK_PLL Multiplication factor = CK_PLLIx16
    //  Select CK_PLLO Divider = CK_PLL/4
    //Select CK_MAIN Source = CK_PLLO
    //Configure PLL->Select APB Prescaler = CK_MAIN/1
    //Configure Peripheral On Mode Clock->DAC = Enable
    //Configure Peripheral On Mode Clock->Port B = Enable
    //Configure Peripheral On Mode Clock->TM10 = Enable
    //Configure Peripheral On Mode Clock->DMA = Enable
	
    //==Set GPIO init 
    //MG32_GPIO_Init.h(Configuration Wizard)->Use GPIOB->PB2
    //GPIO port initial is 0xFFFF
    //PB2 mode is AIO
    //PB2 function GPB2
    
    // ------------------------------------------------------------------------
    // 1.Initial TM10 timer : counter range is 300*65536 clocks.
    // ------------------------------------------------------------------------
    mTM10.Instance                  = TM10;
    mTM10.Init.TM_CounterMode       = TM_FULLCOUNTER_UP;
    mTM10.Init.TM_Period            = 300;
    mTM10.Init.TM_Prescaler         = 0;
    MID_TM_Base_Init(&mTM10);
    
    // ------------------------------------------------------------------------
    // 2.Initial TM10 clock mode.
    // ------------------------------------------------------------------------
    CKConfig.TM_ClockSource         = TM_INTERNAL_CLOCK;
    CKConfig.TM_ExternalClockSource = 0;
    CKConfig.TM_INTClockDivision    = TM_INTERNALCLOCK_DIVDER_DIV1;
    CKConfig.TM_InternalClockSource = TM_INTERNALCLOCK_PROC;
    MID_TM_ConfigClockSource(&mTM10, &CKConfig);  

    // ------------------------------------------------------------------------
    // 3.Initial TM10 TRGO configuration.
    // ------------------------------------------------------------------------
    TM_TRGOConfig.MasterOutputTrigger   = TM_TRGO_UPDATE;
    TM_TRGOConfig.MasterOutputPolarity  = TM_MASTEROUTPUT_BYPASS;
    TM_TRGOConfig.MasterUpdateEvent     = TM_UPDATE_OVERFLOW;
    MID_TM_MasterConfigSynchronization(&mTM10, &TM_TRGOConfig);
    
    // ------------------------------------------------------------------------
    // 4.Start TM10.
    // ------------------------------------------------------------------------
    MID_TM_Base_Start(&mTM10);      

    // ------------------------------------------------------------------------
    // 5.Initial DAC. 
    // ------------------------------------------------------------------------
    mDAC.Instance                   = DAC;
    mDAC.Init.TriggerConverionSrc   = DAC_TRIGGERSOURCE_TM10_TRGO;  // DAC update source from TM10 TRGO
    mDAC.Init.TriggerConverionEdge  = DAC_RISING_EDGE_UPDATE;       // DAC accept rising edge of TM10_TRGO to update DAC
    mDAC.Init.DataAlign             = DAC_ALIGN_10B_R;              // DAC data is 10bit /w right justif
    #if defined(MG32_1ST)
    mDAC.Init.OutputLevel           = DAC_OUTPUTCURRENT_MODE0;      // DAC output ~0.5mA 
    #endif
    mDAC.Init.InterruptMode         = DAC_IT_READY;                 // DAC will trigger INT when READY flag happened.
    
    MID_DAC_Init(&mDAC);


    // ------------------------------------------------------------------------
    // 6.Initial DMA. (M2P)
    // ------------------------------------------------------------------------
    mDMA.Instance		            = DMA;
	mDMA.DMAChannelIndex            = DMAChannel0;                  // only DMA channel0 can support M2M mode  
	mDMA.Init.SrcPeri	            = MID_DMA_MEMORY_READ;          // Source symbol is memory
	mDMA.Init.DesPeri	            = MID_DMA_DAC_WRITE;            // Destination symbol is DAC
	mDMA.Init.BSize 	            = DMA_BSIZE_2BYTE;              // Burst size is 2 byte
	mDMA.Init.MEMMode	            = MID_DMA_MEMORY_NORMAL;        // Normal memory access mode    
    mDMA.Init.LoopMode	            = DMA_LOOP_DISABLE;             // DISABLE Loop mode
    mDMA.Parent                     = &mDAC;
    
	MID_DMA_Init(&mDMA);

    // ------------------------------------------------------------------------
    // 7.DAC with DMA initial.
    // ------------------------------------------------------------------------
    mDAC.DMA_Handle = &mDMA;
    
    #if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) /* ARM Compiler V6 */
        #pragma clang diagnostic push
        #pragma clang diagnostic ignored "-Wcast-align"
            MID_DAC_Start_DMA(&mDAC, (uint32_t *) &DAC_DMA_Pattern, 20);
        #pragma clang diagnostic pop
    #else
        MID_DAC_Start_DMA(&mDAC, (uint32_t *) &DAC_DMA_Pattern, 20);
    #endif
    
}


