/**
  ******************************************************************************
 *
 * @file        Sample_MID_SPI_Slave_TXRX_IT.c
 *
 * @brief       SPIx/URTx slave transmit and receive use interrupt sample code
 *
 * @par         Project
 *              MG32
 * @version     V1.02
 * @date        2024/05/10
 * @author      Megawin Software Center
 * @copyright   Copyright (c) 2020 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 ------------------------------------------------------------------*/
/* Wizard menu ---------------------------------------------------------------*/
#include "MG32_SPI_MID.h"

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define SPI0_NSS            PX(GPIOB_Base,0)                                            /*!< SPI0 NSS pin*/
#define URT0_NSS            PX(GPIOB_Base,10)                                           /*!< URT0 NSS pin*/

/* Private macro -------------------------------------------------------------*/
#define PX(GPIOX,PinNum)    *((volatile uint8_t*)((uint32_t)GPIOX + PinNum + 0x10))     /*!< GPIOX pin (PinNum) read /write */

/* Private variables ---------------------------------------------------------*/
static SPI_HandleTypeDef    mSPI3;

/* Private function prototypes -----------------------------------------------*/
void Sample_MID_SPI_Slave_Transfer_IT (MID_SPI_Struct* MID_Module);
void SPI0_IRQHandler (void);

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



/**
 *******************************************************************************
 * @brief       SPI0/URTx slave transmit and receive use interrupt.
 * @details     1.Initial SPI/URTx.
 *    \n        2.Clear RX buffer
 *    \n        3.Transmit data.
 *    \n        4.Receive data.
 *    \n        5.Transmit data.
 *    \n        6.Receive data.
 * @return      None
 *******************************************************************************
 */
void Sample_MID_SPI_Slave_Transfer_IT (MID_SPI_Struct* MID_Module)
{  
    uint8_t     RX_BUF8[63]={0};
    uint8_t     CNT;


    
    // make sure :
    //===Set CSC init===
    //MG32_CSC_Init.h(Configuration Wizard)
    //Select CK_HS source = CK_IHRCO
    //Select IHRCO = 12M
    //Select CK_MAIN Source = CK_HS
    //Configure PLL->Select APB Prescaler = CK_MAIN/1
    //Configure Peripheral On Mode Clock->SPI0 = Enable
    //Configure Peripheral On Mode Clock->GPIOB = Enable
    //
    //Keil toolbar "Manage Run-Time Environment" clik.
    //"IRQ handler" must be ticked in "MG32_ChipInit_Wizard"
    //When use SPI0, "Enable SPI0 NVIC" of "MG32_IRQ_Handler" must be ticked in "MG32_ChipInit_Wizard"
    //When use URT0, "Enable URT0 NVIC" of "MG32_IRQ_Handler" must be ticked in "MG32_ChipInit_Wizard"
    //When use URT1, "Enable URT1 NVIC" of "MG32_IRQ_Handler" must be ticked in "MG32_ChipInit_Wizard"
    //
    /*===Set GPIO init SPI0 for SPI0===*/
    //1. MOSI Pin
    //    (1).MG32_GPIO_Init.h(Configuration Wizard)->Use GPIOB->Pin3
    //    (2).GPIO port initial is 0xFFFF
    //    (3).Pin3 mode is DIN (Data input)
    //    (4).Pin3 pull-up resister Enable
    //    (5).Pin3 function SPI0_MOSI
    //2. MISO Pin
    //    (1).MG32_GPIO_Init.h(Configuration Wizard)->Use GPIOB->Pin1
    //    (2).GPIO port initial is 0xFFFF
    //    (3).Pin1 mode is PPO (Push pull output)
    //    (4).Pin1 pull-up resister Enable
    //    (5).Pin1 function SPI0_MISO
    //3. SPICLK Pin
    //    (1).MG32_GPIO_Init.h(Configuration Wizard)->Use GPIOB->Pin2
    //    (2).GPIO port initial is 0xFFFF
    //    (3).Pin2 mode is DIN (Data input)
    //    (4).Pin2 pull-up resister Enable
    //    (5).Pin2 function SPI0_CLK
    //4. NSS Pin
    //    (1).MG32_GPIO_Init.h(Configuration Wizard)->Use GPIOB->Pin10
    //    (2).GPIO port initial is 0xFFFF
    //    (3).Pin0 mode is DIN (Data input)
    //    (4).Pin0 pull-up resister Enable
    //    (5).Pin0 function SPI0_NSS

    // ------------------------------------------------------------------------
    // 1.Initial master clock
    // ------------------------------------------------------------------------
    mSPI3.Instance = MID_Module;
    mSPI3.Init.Mode = SPI_MODE_SLAVE_NSS;
    mSPI3.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
    mSPI3.Init.NSS = SPI_NSS_IN_HARDWARE;
    mSPI3.Init.DataLine = SPI_STANDARD_SPI;
    mSPI3.Init.DataSize = SPI_DATASIZE_8BIT;
    mSPI3.Init.CLKPolarity = SPI_POLARITY_LOW;
    mSPI3.Init.CLKPhase = SPI_PHASE_1EDGE;
    mSPI3.Init.ClockDivider = SPI_CLOCKDIVIDER_8;
    mSPI3.Init.FirstBit = SPI_FIRSTBIT_MSB;
    mSPI3.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
    if (MID_SPI_Init(&mSPI3) != MID_OK)                 // When SPI initial failure, stop at there.
    {
        while(1);
    }

    // SPI slave mode transmitted data directly update enable
#if defined(MG32_2ND) || defined(MG32_3RD) || defined(MG32_4TH)
    if((mSPI3.Init.Mode & SPI_MDS_MASK) == 0) 
        mSPI3.Instance->CR2.B[3] = SPI_CR2_TXUPD_EN_mask_b3;
#endif
    
    // ------------------------------------------------------------------------
    // 2.Clear RX buffer
    // ------------------------------------------------------------------------
    for(CNT=0; CNT<63; CNT++)                       
    {
        RX_BUF8[CNT] = 0;       // Clear RX_BUF data
    }

    // ------------------------------------------------------------------------
    // 3.Receive data
    // ------------------------------------------------------------------------
    MID_SPI_Receive_IT(&mSPI3, &RX_BUF8[0], 63);
    while(__MID_SPI_GET_STATE(&mSPI3) != MID_SPI_STATE_READY);
    
    // ------------------------------------------------------------------------
    // 4.Transmit data
    // ------------------------------------------------------------------------
    MID_SPI_Transmit_IT(&mSPI3, &RX_BUF8[0], 63);
    while(__MID_SPI_GET_STATE(&mSPI3) != MID_SPI_STATE_READY);

    // ------------------------------------------------------------------------
    // 5.Receive data
    // ------------------------------------------------------------------------
    while((mSPI3.Instance->CR2.W & SPI_CR2_NSS_SWI_mask_w) == 0);
    MID_SPI_Receive_IT(&mSPI3, &RX_BUF8[0], 63);
    while(__MID_SPI_GET_STATE(&mSPI3) != MID_SPI_STATE_READY);

    // ------------------------------------------------------------------------
    // 6.Transmit data
    // ------------------------------------------------------------------------
    while((mSPI3.Instance->CR2.W & SPI_CR2_NSS_SWI_mask_w) == 0);
    MID_SPI_Transmit_IT(&mSPI3, &RX_BUF8[0], 63);
    while(__MID_SPI_GET_STATE(&mSPI3) != MID_SPI_STATE_READY);
}


/**
 *******************************************************************************
 * @brief       SPI module IRQ
 * @details  
 * @return  
 * @note
 *******************************************************************************
 */
void SPI0_IRQHandler (void)
{
    MID_SPI_IRQHandler(&mSPI3);
}


/**
 *******************************************************************************
 * @brief       Tx Transfer completed callback.
 * @details  
 * @param[in]   mSPI:
 *  @arg\b          mSPI. mSPI pointer to a SPI_HandleTypeDef structure that 
 *                  contains the configuration information for SPI module.
 * @return      none
 * @note
 * @par         Example
 * @code
    MID_SPI_TxCpltCallback(mSPI);
 * @endcode
 *******************************************************************************
 */
void MID_SPI_TxCpltCallback(SPI_HandleTypeDef *mSPI)
{
    UNUSED(mSPI);
    // To do ...
}


/**
 *******************************************************************************
 * @brief       Rx Transfer completed callback.
 * @details  
 * @param[in]   mSPI:
 *  @arg\b          mSPI. mSPI pointer to a SPI_HandleTypeDef structure that 
 *                  contains the configuration information for SPI module.
 * @return      none
 * @note
 * @par         Example
 * @code
    MID_SPI_RxCpltCallback(mSPI);
 * @endcode
 *******************************************************************************
 */
void MID_SPI_RxCpltCallback(SPI_HandleTypeDef *mSPI)
{
    UNUSED(mSPI);
    // To do ...
}


/**
 *******************************************************************************
 * @brief       Tx and Rx Transfer completed callback.
 * @details  
 * @param[in]   mSPI:
 *  @arg\b          mSPI. mSPI pointer to a SPI_HandleTypeDef structure that 
 *                  contains the configuration information for SPI module.
 * @return      none
 * @note
 * @par         Example
 * @code
    MID_SPI_TxRxCpltCallback(mSPI);
 * @endcode
 *******************************************************************************
 */
void MID_SPI_TxRxCpltCallback(SPI_HandleTypeDef *mSPI)
{
    UNUSED(mSPI);
    // To do ...
}



