

/**
 ******************************************************************************
 *
 * @file        Sample_URT0_SPISlaveMode_DMA.c
 * @brief       SPI mode of URT module use DMA sample code.
 *
 * @par         Project
 *              MG32
 * @version     V1.00
 * @date        2025/05/05
 * @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_GPIO_DRV.h"
#include "MG32_URT_DRV.h"
#include "MG32_DMA_DRV.h"

/* Wizard menu ---------------------------------------------------------------*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define SMP_DMA_URT       URT0

#define SMP_URT_TX_PINX   PINB(8)
#define SMP_URT_RX_PINX   PINB(9)
#define SMP_URT_CLK_PINX  PINB(11)
#define SMP_URT_NSS_PINX  PINB(10)

#define SMP_URT_TX_AFS    3  
#define SMP_URT_RX_AFS    3  
#define SMP_URT_CLK_AFS   11  
#define SMP_URT_NSS_AFS   3 


/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
static uint8_t SMP_DAM_TXBuf[48] = 
{
    0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10,
    0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20,
    0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x30,
    0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x40,
    0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
};    

static uint8_t SMP_DMA_TXDummy;

static uint8_t SMP_DAM_RXBuf[48];



/* Private function prototypes -----------------------------------------------*/
void Sample_URT_SPISlave_Init(void);
void Sample_URT_SPISlaveTxDMA(void);
void Sample_URT_SPISlaveRxDMA(void);
void Sample_URT_SPISlaveTxRxDMA(void);
void Sample_URT_SPISlaveDMA(void);

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

/**
 *******************************************************************************
 * @brief	   URT initial (Configure to SPI Slave mode)
 * @details 
 * @return     
 * @exception   
 * @note           
 *******************************************************************************
 */
void Sample_URT_SPISlave_Init(void)
{
    PIN_InitTypeDef     URT_mSPI_PINX;
    URT_Data_TypeDef    URT_mSPI_Datastruct;
    URT_BRG_TypeDef     URT_mSPI_BRGStruct;
    
    
    /*GPIO initial*/
    URT_mSPI_PINX.PINX_Mode				  = PINX_Mode_PushPull_O;
    URT_mSPI_PINX.PINX_PUResistant        = PINX_PUResistant_Disable;
    URT_mSPI_PINX.PINX_Speed              = PINX_Speed_High;
    URT_mSPI_PINX.PINX_OUTDrive           = PINX_OUTDrive_Level0;
    URT_mSPI_PINX.PINX_FilterDivider      = PINX_FilterDivider_Bypass;
    URT_mSPI_PINX.PINX_Inverse            = PINX_Inverse_Disable;
    
    URT_mSPI_PINX.PINX_Alternate_Function = SMP_URT_TX_AFS;
    GPIO_PinMode_Config(SMP_URT_TX_PINX,&URT_mSPI_PINX);
    
    URT_mSPI_PINX.PINX_Mode				  = PINX_Mode_Digital_I;
    URT_mSPI_PINX.PINX_PUResistant        = PINX_PUResistant_Disable;
    URT_mSPI_PINX.PINX_Alternate_Function = SMP_URT_RX_AFS;
    GPIO_PinMode_Config(SMP_URT_RX_PINX,&URT_mSPI_PINX);
    
    URT_mSPI_PINX.PINX_Alternate_Function = SMP_URT_CLK_AFS;
    GPIO_PinMode_Config(SMP_URT_CLK_PINX,&URT_mSPI_PINX);
    
    URT_mSPI_PINX.PINX_Alternate_Function = SMP_URT_NSS_AFS;
    GPIO_PinMode_Config(SMP_URT_NSS_PINX,&URT_mSPI_PINX);
    
    
    /*SPI data character configure*/
    URT_mSPI_Datastruct.URT_TX_DataLength = URT_DataLength_8;     /*!< Data bit is 8 bits*/
    URT_mSPI_Datastruct.URT_RX_DataLength = URT_DataLength_8;     /*!< Data bit is 8 bits*/
    URT_mSPI_Datastruct.URT_TX_DataOrder  = URT_DataTyped_MSB;    /*!< Data order is MSB*/
    URT_mSPI_Datastruct.URT_RX_DataOrder  = URT_DataTyped_MSB;    /*!< Data order is MSB*/
    URT_mSPI_Datastruct.URT_TX_Parity     = URT_Parity_No;
    URT_mSPI_Datastruct.URT_RX_Parity     = URT_Parity_No;
    URT_mSPI_Datastruct.URT_TX_StopBits   = URT_StopBits_1_0;
    URT_mSPI_Datastruct.URT_RX_StopBits   = URT_StopBits_1_0;
    URT_mSPI_Datastruct.URT_TX_DataInverse= DISABLE;
    URT_mSPI_Datastruct.URT_RX_DataInverse= DISABLE;
    URT_DataCharacter_Config(SMP_DMA_URT,&URT_mSPI_Datastruct);
    
    /*SPI bit rate configure */
    URT_BaudRateGenerator_Cmd(SMP_DMA_URT,DISABLE);
    URT_mSPI_BRGStruct.URT_InternalClockSource    = URT_BDClock_PROC;
    URT_mSPI_BRGStruct.URT_BaudRateMode           = URT_BDMode_Separated;
    URT_mSPI_BRGStruct.URT_BaudRateCounterReload  = 0;
    URT_mSPI_BRGStruct.URT_PrescalerCounterReload = 0;
    URT_BaudRateGenerator_Config(SMP_DMA_URT,&URT_mSPI_BRGStruct); 
    URT_BaudRateGenerator_Cmd(SMP_DMA_URT,ENABLE);
    
    URT_TXClockSource_Select(SMP_DMA_URT,URT_TXClock_EXT);                        
    URT_RXClockSource_Select(SMP_DMA_URT,URT_RXClock_EXT);                        
    URT_RXOverSamplingMode_Select(SMP_DMA_URT,URT_RXSMP_3TIME);
    URT_RXOverSamplingSampleNumber_Select(SMP_DMA_URT,3);
    URT_TXOverSamplingSampleNumber_Select(SMP_DMA_URT,3);
    
    /*Buffer initial*/
    URT_RXShadowBufferThreshold_Select(SMP_DMA_URT,URT_RXTH_1BYTE);
    
    URT_ClearTXData(SMP_DMA_URT);
    URT_ClearRXData(SMP_DMA_URT);
    
    /*Mode configure*/
    URT_Mode_Select(SMP_DMA_URT,URT_SYNC_mode);
    URT_DataLine_Select(SMP_DMA_URT,URT_DataLine_2);
    URT_CLKSignal_Cmd(SMP_DMA_URT,DISABLE);
    URT_NssInput_Cmd(SMP_DMA_URT,ENABLE);
    
    /*SPI related configure*/
    URT_SYNCMode_Select(SMP_DMA_URT, URT_SYNC_SLAVE);
    URT_CPHAMode_Select(SMP_DMA_URT,URT_CPHA0_LeadEdge);
    URT_CPOLMode_Select(SMP_DMA_URT,URT_CPOL0_Low);
    
    
    /*Flag initial*/
    URT_ClearITFlag(SMP_DMA_URT,(URT_IT_TC|URT_IT_RX));

    /*Enable URT*/
    URT_TX_Cmd(SMP_DMA_URT,ENABLE);
    URT_RX_Cmd(SMP_DMA_URT,ENABLE);
    URT_Cmd(SMP_DMA_URT,ENABLE);
    
}

/**
 *******************************************************************************
 * @brief	   SPI TX only sample code.
 * @details 
 * @return     
 * @exception   
 * @note           
 *******************************************************************************
 */
void Sample_URT_SPISlaveTxDMA(void)
{
    DMA_BaseInitTypeDef  mSPI_TxDMA;
    
    /*DMA initial*/
    DMA_Cmd(ENABLE);
    
    DMA_Channel_Cmd(DMAChannel0, ENABLE);
    DMA_BaseInitStructure_Init(&mSPI_TxDMA);
    mSPI_TxDMA.DMAChx          = DMAChannel0;                          
    mSPI_TxDMA.DMALoopCmd      = DISABLE;
    mSPI_TxDMA.SrcSINCSel      = ENABLE;               /*!< DMA source memory address increase in transmit every data*/
    mSPI_TxDMA.DestDINCSel     = DISABLE;                                     
    mSPI_TxDMA.SrcSymSel       = DMA_MEM_Read;         /*!< DMA source is memory.*/
    mSPI_TxDMA.DestSymSel      = DMA_URT0_TX;          /*!< DMA destination is URT_TX.*/
    mSPI_TxDMA.BurstDataSize   = DMA_BurstSize_1Byte;  
    mSPI_TxDMA.DMATransferNUM  = 48;                   
    mSPI_TxDMA.DMASourceAddr   = SMP_DAM_TXBuf;        /*!< DMA source memory initial address.*/ 
    DMA_Base_Init(&mSPI_TxDMA);
    
    /*Clear flag*/
    DMA_ClearFlag(DMA,(DMA_FLAG_CH0_GIF | DMA_FLAG_CH0_TCF | DMA_FLAG_CH0_THF | DMA_FLAG_CH0_ERRF));  /*!< To start DMA has to clear DMA flag*/
    URT_ClearITFlag(SMP_DMA_URT,(URT_IT_TC|URT_IT_RX));
    
    /*Disable RX */
    URT_RX_Cmd(SMP_DMA_URT,DISABLE);
    
    /*Start DMA TX */
    URT_TXDMA_Cmd(SMP_DMA_URT,ENABLE);
    DMA_StartRequest(DMAChannel0);
    
    /*Wait DMA complete*/
    while((URT_GetITAllFlagStatus(SMP_DMA_URT) & URT_IT_TC)==0);  /*!< Wait URT transmit last bit of last data*.*/
    URT_RX_Cmd(SMP_DMA_URT,ENABLE);
}
/**
 *******************************************************************************
 * @brief	   URT TX and RX DMA sample code
 * @details 
 * @return     
 * @exception   
 * @note           
 *******************************************************************************
 */
void Sample_URT_SPISlaveTxRxDMA(void)
{
    DMA_BaseInitTypeDef  mSPI_TxRxDMA;
    
    /*DMA enable*/
    DMA_Cmd(ENABLE);
    
    /*DMA TX initial (Use DAM channel 0)*/
    DMA_Channel_Cmd(DMAChannel0, ENABLE);
    DMA_BaseInitStructure_Init(&mSPI_TxRxDMA);
    mSPI_TxRxDMA.DMAChx          = DMAChannel0;                          
    mSPI_TxRxDMA.DMALoopCmd      = DISABLE; 
    mSPI_TxRxDMA.SrcSINCSel      = ENABLE;                  /*!< DMA source memory address increase in transmit every data*/ 
    mSPI_TxRxDMA.DestDINCSel     = DISABLE;                            
    mSPI_TxRxDMA.SrcSymSel       = DMA_MEM_Read;            /*!< DMA source is memory.*/
    mSPI_TxRxDMA.DestSymSel      = DMA_URT0_TX;             /*!< DMA destination is URT_TX.*/
    mSPI_TxRxDMA.BurstDataSize   = DMA_BurstSize_1Byte;
    mSPI_TxRxDMA.DMATransferNUM  = 48;
    mSPI_TxRxDMA.DMASourceAddr   = SMP_DAM_TXBuf;           /*!< DMA source memory initial address.*/ 
    DMA_Base_Init(&mSPI_TxRxDMA);
    
    /*DMA RX initial (Use DAM channel 1)*/
    DMA_Channel_Cmd(DMAChannel1, ENABLE);
    DMA_BaseInitStructure_Init(&mSPI_TxRxDMA);
    mSPI_TxRxDMA.DMAChx             = DMAChannel1;                          
    mSPI_TxRxDMA.DMALoopCmd         = DISABLE;
    mSPI_TxRxDMA.SrcSINCSel         = DISABLE;    
    mSPI_TxRxDMA.DestDINCSel        = ENABLE;                /*!< DMA destination memory address increase in transmit every data*/          
    mSPI_TxRxDMA.SrcSymSel          = DMA_URT0_RX;           /*!< DMA source is URT_RX.*/
    mSPI_TxRxDMA.DestSymSel         = DMA_MEM_Write;         /*!< DMA destination is memory.*/
    mSPI_TxRxDMA.BurstDataSize      = DMA_BurstSize_1Byte;   
    mSPI_TxRxDMA.DMATransferNUM     = 48;                    
    mSPI_TxRxDMA.DMADestinationAddr = SMP_DAM_RXBuf;         /*!< DMA destination memory initial address.*/ 
    DMA_Base_Init(&mSPI_TxRxDMA);
    
    /*Clear flag*/
    DMA_ClearFlag(DMA,(DMA_FLAG_CH0_GIF | DMA_FLAG_CH0_TCF | DMA_FLAG_CH0_THF | DMA_FLAG_CH0_ERRF) |\
                      (DMA_FLAG_CH1_GIF | DMA_FLAG_CH1_TCF | DMA_FLAG_CH1_THF | DMA_FLAG_CH1_ERRF));   /*!< To start DMA has to clear DMA flag*/
    URT_ClearITFlag(SMP_DMA_URT,(URT_IT_TC|URT_IT_RX));
    
    /*Start DMA TX */
    URT_TXDMA_Cmd(SMP_DMA_URT,ENABLE);
    URT_RXDMA_Cmd(SMP_DMA_URT,ENABLE);
    DMA_StartRequest(DMAChannel1);
    DMA_StartRequest(DMAChannel0);
    
    /*Wait DMA complete*/
    while((URT_GetITAllFlagStatus(SMP_DMA_URT) & URT_IT_TC)==0);    /*!< Wait URT transmit last bit of last data*.*/
    while((DMA_GetAllFlagStatus(DMA) & DMA_FLAG_CH1_TCF)==0);       /*!< Wait URT receive last data and saving to memory.*/ 
}

/**
 *******************************************************************************
 * @brief	  URT receive and transmit dummy byte DMA sample code.
 * @details 
 * @return     
 * @exception   
 * @note           
 *******************************************************************************
 */
void Sample_URT_SPISlaveRxDMA(void)
{
    DMA_BaseInitTypeDef  mSPI_RxDMA;
    
    /*DMA enable*/
    DMA_Cmd(ENABLE);
    
    /*DMA TX initial (Use DAM channel 0)*/
    DMA_Channel_Cmd(DMAChannel0, ENABLE);
    DMA_BaseInitStructure_Init(&mSPI_RxDMA);
    mSPI_RxDMA.DMAChx          = DMAChannel0;                          
    mSPI_RxDMA.DMALoopCmd      = DISABLE;
    mSPI_RxDMA.SrcSINCSel      = DISABLE;                   /*!< DMA source memory address no increase in transmit every data*/  
    mSPI_RxDMA.DestDINCSel     = DISABLE;                          
    mSPI_RxDMA.SrcSymSel       = DMA_MEM_Read;              /*!< DMA source is memory.*/
    mSPI_RxDMA.DestSymSel      = DMA_URT0_TX;               /*!< DMA destination is URT_TX.*/
    mSPI_RxDMA.BurstDataSize   = DMA_BurstSize_1Byte;
    mSPI_RxDMA.DMATransferNUM  = 48;
    mSPI_RxDMA.DMASourceAddr   = &SMP_DMA_TXDummy;          /*!< DMA source memory initial address.*/ 
    DMA_Base_Init(&mSPI_RxDMA);
    
    /*DMA RX initial (Use DAM channel 1)*/
    DMA_Channel_Cmd(DMAChannel1, ENABLE);
    DMA_BaseInitStructure_Init(&mSPI_RxDMA);
    mSPI_RxDMA.DMAChx             = DMAChannel1;                          
    mSPI_RxDMA.DMALoopCmd         = DISABLE;
    mSPI_RxDMA.SrcSINCSel         = DISABLE;    
    mSPI_RxDMA.DestDINCSel        = ENABLE;                 /*!< DMA destination memory address increase in transmit every data*/           
    mSPI_RxDMA.SrcSymSel          = DMA_URT0_RX;            /*!< DMA source is URT_RX.*/
    mSPI_RxDMA.DestSymSel         = DMA_MEM_Write;          /*!< DMA destination is memory.*/
    mSPI_RxDMA.BurstDataSize      = DMA_BurstSize_1Byte;
    mSPI_RxDMA.DMATransferNUM     = 48;
    mSPI_RxDMA.DMADestinationAddr = SMP_DAM_RXBuf;          /*!< DMA destination memory initial address.*/ 
    DMA_Base_Init(&mSPI_RxDMA);
    
    /*Clear flag*/
    DMA_ClearFlag(DMA,(DMA_FLAG_CH0_GIF | DMA_FLAG_CH0_TCF | DMA_FLAG_CH0_THF | DMA_FLAG_CH0_ERRF) |\
                      (DMA_FLAG_CH1_GIF | DMA_FLAG_CH1_TCF | DMA_FLAG_CH1_THF | DMA_FLAG_CH1_ERRF));   /*!< To start DMA has to clear DMA flag*/
    URT_ClearITFlag(SMP_DMA_URT,(URT_IT_TC|URT_IT_RX));
    
    /*Start DMA TX */
    SMP_DMA_TXDummy = 0x55;                                         /*!< Decide to transmit dummy byte*/
    URT_TXDMA_Cmd(SMP_DMA_URT,ENABLE);                              /*!< Enable URT TX's DMA function*/
    URT_RXDMA_Cmd(SMP_DMA_URT,ENABLE);                              /*!< Enable URT RX's DMA function*/
    DMA_StartRequest(DMAChannel1);                                  /*!< Request DMA channel 1 (URT_RX DMA)*/
    DMA_StartRequest(DMAChannel0);                                  /*!< Request DMA channel 0 (URT_TX DMA)*/
    
    /*Wait DMA complete*/
    while((URT_GetITAllFlagStatus(SMP_DMA_URT) & URT_IT_TC)==0);    /*!< Wait URT transmit last bit of last data*.*/
    while((DMA_GetAllFlagStatus(DMA) & DMA_FLAG_CH1_TCF)==0);       /*!< Wait URT receive last data and saving to memory.*/ 
}


/**
 *******************************************************************************
 * @brief	   CAN sample code main function
 * @details 
 * @return     
 * @exception   
 * @note           
 *******************************************************************************
 */
void Sample_URT_SPISlaveDMA(void)
{
    /*URT configure to SPI master mode*/
    Sample_URT_SPISlave_Init();
    
    /*SPI master DMA for transmitting only*/
    Sample_URT_SPISlaveTxDMA();
    
    /*SPI master DMA for transmitting and receiving*/
    Sample_URT_SPISlaveTxRxDMA();
    
    /*SPI master DMA for receiving and transmitting dummy byte*/
    Sample_URT_SPISlaveRxDMA();

}



