/**
  ******************************************************************************
 *
 * @file        Sample_MID_SPI_TemperatureDetector.c
 *
 * @brief       For MAX31865 RTD to digital converter sample code used middleware
 *
 * @par         Project
 *              MG32
 * @version     V1.00
 * @date        2023/05/09
 * @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 ------------------------------------------------------------------*/
#include "MG32_SPI_MID.h"

/* Wizard menu ---------------------------------------------------------------*/
/* 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     mSPI0;

/* Private function prototypes -----------------------------------------------*/
void Sample_MID_SPI_TemperatureDetector (MID_SPI_Struct* MID_Module);
void API_ReadRTDData (SPI_HandleTypeDef *mSPI, uint8_t StartAddress, uint8_t *pData, uint32_t Size);
void API_WriteRTDData (SPI_HandleTypeDef *mSPI, uint8_t StartAddress, uint8_t *pData, uint32_t Size);

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



/**
 *******************************************************************************
 * @brief       API read MAX31865 data.
 * @details  
 * @param[in]   mSPI:
 *  @arg\b          mSPI. mSPI pointer to a SPI_HandleTypeDef structure that 
 *                  contains the configuration information for SPI module.
 * @param[in]   StartAddress:
 *  @arg\b          0x00h ~ 0x07h
 * @param[in]   pData pointer to reception data buffer
 * @param[in]   Size:
 *                  0 ~ 16 
 * @return      none
 * @note        Support MAX31865.
 * @par         Example
 * @code
    API_ReadRTDData(mSPI, 0x00, &RX_BUF[0], 5);
 * @endcode
 *******************************************************************************
 */
void API_ReadRTDData (SPI_HandleTypeDef *mSPI, uint8_t StartAddress, uint8_t *pData, uint32_t Size)
{
    uint8_t TX_CNT;                                                                 // TX counter
    uint8_t MAX_TX_BUF8[16]={0};                                                    // MAX31865 TX buffer
    
    
    for(TX_CNT=0; TX_CNT<(Size +1); TX_CNT++)                                       // Clear MAX_TX_BUF8[]
    {
        MAX_TX_BUF8[TX_CNT]=0;
    }
    MAX_TX_BUF8[0] = StartAddress;                                                  // Set Address
    
    SPI0_NSS = CLR;                                                                 // SPI0_NSS output 0
    URT0_NSS = CLR;                                                                 // URT0_NSS output 0
    MID_SPI_TransmitReceive(mSPI, &MAX_TX_BUF8[0], pData, (Size +1), 0x80000000);   // SPI transmit and receive 
    SPI0_NSS = SET;                                                                 // SPI0_NSS output 1
    URT0_NSS = SET;                                                                 // URT0_NSS output 1
}


/**
 *******************************************************************************
 * @brief       API write MAX31865 data.
 * @details  
 * @param[in]   mSPI:
 *  @arg\b          mSPI. mSPI pointer to a SPI_HandleTypeDef structure that 
 *                  contains the configuration information for SPI module.
 * @param[in]   StartAddress:
 *  @arg\b          0x00h ~ 0x07h
 * @param[in]   pData pointer to reception data buffer
 * @param[in]   Size:
 *                  0 ~ 16 
 * @return      none
 * @note        Support MAX31865.
 * @par         Example
 * @code
    API_WriteRTDData(mSPI, Address, &TX_BUF[0], 5);
 * @endcode
 *******************************************************************************
 */
void API_WriteRTDData (SPI_HandleTypeDef *mSPI, uint8_t StartAddress, uint8_t *pData, uint32_t Size)
{
    uint8_t TX_CNT;                                                                 // TX counter
    uint8_t MAX_TX_BUF8[10]={0};                                                    // MAX31865 TX buffer
    
    
    
    MAX_TX_BUF8[0] = StartAddress;                                                  // Set Address
    for(TX_CNT=0; TX_CNT<Size; TX_CNT++)                                            // Move data to MAX_TX_BUF8
    {
        MAX_TX_BUF8[(TX_CNT + 1)] = *pData;
        pData++;
    }
    
    SPI0_NSS = CLR;                                                                 // SPI0_NSS output 0
    URT0_NSS = CLR;                                                                 // URT0_NSS output 0
    MID_SPI_Transmit(mSPI, &MAX_TX_BUF8[0], (Size + 1), 0x80000000);                // SPI transmit data
    SPI0_NSS = SET;                                                                 // SPI0_NSS output 1
    URT0_NSS = SET;                                                                 // URT0_NSS output 1
}


/**
 *******************************************************************************
 * @brief       SPI0 temperature detector 
 * @details     1.Initial SPI.
 *    \n        2.Setting TX/RX Buffer Transmit data.
 *    \n        3.Receive data.
 *    \n        4.Transmit data.
 *    \n        5.Receive data.
 * @return      None
 *******************************************************************************
 */
void Sample_MID_SPI_TemperatureDetector (MID_SPI_Struct* MID_Module)
{  
    uint8_t     TX_BUF8[10]={0};
    uint8_t     RX_BUF8[10]={0};
    uint8_t     RTD_ResistanceData[2]={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->URT0 = Enable
    //Configure Peripheral On Mode Clock->URT1 = Enable
    //Configure Peripheral On Mode Clock->GPIOB = Enable

    /*===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 PPO (Push pull output)
    //    (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 DIN (Data input)
    //    (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 PPO (Push pull output)
    //    (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 PPO (Push pull output)
    //    (4).Pin0 pull-up resister Enable
    //    (5).Pin0 function GPB0

    /*===Set GPIO init SPI0 for URT0===*/
    //1. MOSI Pin
    //    (1).MG32_GPIO_Init.h(Configuration Wizard)->Use GPIOB->Pin8
    //    (2).GPIO port initial is 0xFFFF
    //    (3).Pin8 mode is PPO (Push pull output)
    //    (4).Pin8 pull-up resister Enable
    //    (5).Pin8 function URT0_TX
    //2. MISO Pin
    //    (1).MG32_GPIO_Init.h(Configuration Wizard)->Use GPIOB->Pin9
    //    (2).GPIO port initial is 0xFFFF
    //    (3).Pin9 mode is DIN (Data input)
    //    (4).Pin9 pull-up resister Enable
    //    (5).Pin9 function URT0_RX
    //3. SPICLK Pin
    //    (1).MG32_GPIO_Init.h(Configuration Wizard)->Use GPIOC->Pin3
    //    (2).GPIO port initial is 0xFFFF
    //    (3).Pin3 mode is PPO (Push pull output)
    //    (4).Pin3 pull-up resister Enable
    //    (5).Pin3 function URT0_CLK
    //4. NSS Pin
    //    (1).MG32_GPIO_Init.h(Configuration Wizard)->Use GPIOB->Pin10
    //    (2).GPIO port initial is 0xFFFF
    //    (3).Pin10 mode is PPO (Push pull output)
    //    (4).Pin10 pull-up resister Enable
    //    (5).Pin10 function GPB10

    // ------------------------------------------------------------------------
    // 1.Initial SPI/URTx
    // ------------------------------------------------------------------------
    mSPI0.Instance = MID_Module;
    mSPI0.Init.Mode = SPI_MODE_MASTER;
    mSPI0.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
    mSPI0.Init.NSS = SPI_NSS_HARDWARE;
    mSPI0.Init.DataLine = SPI_STANDARD_SPI;
    mSPI0.Init.DataSize = SPI_DATASIZE_8BIT;
    mSPI0.Init.CLKPolarity = SPI_POLARITY_LOW;
    mSPI0.Init.CLKPhase = SPI_PHASE_1EDGE;
    mSPI0.Init.ClockDivider = SPI_CLOCKDIVIDER_4;
    mSPI0.Init.FirstBit = SPI_FIRSTBIT_MSB;
    mSPI0.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
    if (MID_SPI_Init(&mSPI0) != MID_OK)                                 // When SPI initial failure, stop at here.
    {
        while(1);
    }

    // ------------------------------------------------------------------------
    // 2. Setting TX/RX Buffer Transmit data.
    // ------------------------------------------------------------------------
    for(CNT=0; CNT<10; CNT++)                                           // Clear RX_BUF data                      
    {
        RX_BUF8[CNT] = CNT;       
    }

    // ------------------------------------------------------------------------
    // 3. Receive data
    // ------------------------------------------------------------------------
    API_ReadRTDData(&mSPI0, 0x00, &RX_BUF8[0], 8);                // Get Configuration, RTD, High Fault Threshold, Low Fault Threshol and Fault Status.
    for(CNT=0; CNT<8; CNT++)                                            // TX_BUF8[] move to RX_BUF8[];
    {
        TX_BUF8[CNT] = RX_BUF8[CNT];
    }

    // ------------------------------------------------------------------------
    // 4. Transmit data
    // ------------------------------------------------------------------------
    TX_BUF8[0] = 0x5A;                                                  // Setting
    API_WriteRTDData(&mSPI0, 0x80, &TX_BUF8[0], 1);               // Configure Configuration.
    
    TX_BUF8[3] = 0x53;                                                  // Setting TX_BUF8[3] High Fault Threshold MSB
    TX_BUF8[4] = 0x54;                                                  // Setting High Fault Threshold LSB
    TX_BUF8[5] = 0x55;                                                  // Setting Low Fault Threshold MSB
    TX_BUF8[6] = 0x56;                                                  // Setting Low Fault Threshold LSB
    API_WriteRTDData(&mSPI0, 0x83, &TX_BUF8[3], 4);               // Configure High Fault Threshold and Low Fault Threshold.
    
    // ------------------------------------------------------------------------
    // 5. Receive data
    // ------------------------------------------------------------------------
    API_ReadRTDData(&mSPI0, 0x01, &RTD_ResistanceData[0], 2);     // Get RTD.
}



