
/**
 ******************************************************************************
 *
 * @file        BSP_DHT_AM2302.h
 * @brief       This file contains all the functions prototypes for the BSP_DHT_AM2302.c 
 *              firmware library.
 *
 * @par         Project
 *              MG32
 * @version     V1.00
 * @date        2024/01/08
 * @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.
 *******************************************************************************
 *******************************************************************************
 */


/*==============================================================================
                                 User NOTES
How To use this function:
-----------------------
   + DHT_begin() - Initial sensor and TM36.
   + DHT_read() - Get enviroment Humidity & Temperature by AM2302.
   + DHT_readHumidity - Get Humidity.
   + DHT_readTemperature - Get Temperature. (default Celcius)
   + DHT_convertCtoF - Converts Celcius to Fahrenheit.

Example:
-----------------------
    DHT_begin();
    
    // Wait a few seconds between measurements.
    delay(2000);

    // Start AM2302 peripheral
    if (DHT_read() == FALSE)
        break;
    
    // Get Humidity
    Humidity = DHT_readHumidity();
    
    // Get Temperature
    Temperature = DHT_readTemperature(Celcius);


Driver architecture:
--------------------
   + MG32_GPIO_DRV
   + MG32_TM_DRV

Known Limitations:
------------------
   1- Run in 48MHz. (CSC control).
   2- GPIO PA12 must be GPIO mode.
==============================================================================*/

/*==============================================================================
                                 Require parameter
Require module : CSC / GPIO / TM36

CSC Module :
    Clock source                : CK_IHRCO (12M Hz)
    Clock frequency             : CK_MAIN select CK_PLLO (PLL to 48MHz)
    CK_APB frequency            : 48MHz
    CK_AHB frequency            : 48MHz
    Clock enable in 'On Mode'   : GPIOB / TM36

GPIO pin configuration : 
    Pin /   IO mode   /   AFS
    ---   ------------  --------
    PA12 / ODO+Pull up / TM36_IC0
                                           
TM36 Module :                   
    TM36 input capture 
    
==============================================================================*/

/* Includes ------------------------------------------------------------------*/
#include "MG32__Common_DRV.h"
#include "MG32_TM_DRV.h"
#include "MG32_GPIO_DRV.h"

/* Wizard menu ---------------------------------------------------------------*/
/* Private typedef -----------------------------------------------------------*/
/**
 *************************************************
 *  @union		TimerAlarm
 *				Alarm tick (45us / 800us / 1ms / 2sec)
 *************************************************
 */
typedef enum 
{
    Time45us,
    Time800us,
    Time1ms,
    Time2sec,
} TimerAlarm;

/**
 *************************************************
 *  @union		TimerCapture
 *				Set TM36 capture time unit (us / ms)
 *************************************************
 */
typedef enum 
{
    Capture_us,
    Capture_ms,
} TimerCapture;


/** 
 * @enum        DHT_Structure
 * @brief       Structure that stores state and functions for DHT
 */        
typedef struct  
{
    // ------------------------------------------------------------------------
    void (*begin)(void);
    float (*convertCtoF)(float);
    float (*convertFtoC)(float);
    float (*readTemperature)(boolean S);
    float (*readHumidity)(void);
    boolean (*read)(void);    
    
    // ------------------------------------------------------------------------
    uint8_t data[5];
    uint8_t _pin, _type;
    uint32_t _lastreadtime, _maxcycles;
    boolean _lastresult;
    uint8_t pullTime; // Time (in usec) to pull up data line before reading
    
} DHT_Structure;


/* Private define ------------------------------------------------------------*/

/**
 * @name	Read_AM2302_Pin
 *   		AM2302 Output pin
 */ 
//!@{
#define GPIO_PinStruct              PINA(12)
#define GPIO_Pin_AFS                0

#define CommunicationPin		    PA12
#define TM36_IC0_Pin_AFS            6
//!@}


/**
 * @name	Temperature unit
 *   		AM2302 Temperature unit
 */ 
//!@{
#define Fahrenheit                  1
#define Celcius                     0
//!@}


/**
 * @name	Control_AM2302_Period
 *   		AM2302 Delay period
 */ 
//!@{
// for 45us     
#define TimerPrescaler_45us         79          // When PSCNT=80 @ CK_APB=48MHz that is 1us.
#define TimerCounter_45us           26          // When CNT=27 @ CK_APB=48MHz that is 1ms.
        
// for 800us        
#define TimerPrescaler_800us        47          // When PSCNT=48 @ CK_APB=48MHz that is 1us.
#define TimerCounter_800us          999         // When CNT=1000 @ CK_APB=48MHz that is 1ms.
        
// for 1ms      
#define TimerPrescaler_1ms          47          // When PSCNT=48 @ CK_APB=48MHz that is 1us.
#define TimerCounter_1ms            999         // When CNT=1000 @ CK_APB=48MHz that is 1ms.
        
// for 2sec     
#define TimerPrescaler_2s           47999       // When PSCNT=48000 @ CK_APB=48MHz that is 1ms.
#define TimerCounter_2s             1999        // When CNT=1000 @ CK_APB=48MHz that is 2sec.
//!@}


/**
 * @name	AM2302_DataIDX
 *   		Data sequence index from AM2302
 */ 
//!@{
//
#define Humidity_HighByte_IDX       0
#define Humidity_LowByte_IDX        1
#define Temperature_HighByte_IDX    2
#define Temperature_LowByte_IDX     3
#define ChecksumByte_IDX            4
//!@}

/* Private macro -------------------------------------------------------------*/
// Set PA8 to be normal GPIO pin.
#define GPIO_CommunicationPin()     GPIO_PinFunction_Select(GPIO_PinStruct, GPIO_Pin_AFS)

// Assert TM36_TOF flag?
#define Timer_GetTimeout()          TM_GetSingleFlagStatus(TM36, TMx_TOF)

// Assert TM36_CF0A flag? (first capture event)
#define Timer_Get1stCapture()       TM_GetSingleFlagStatus(TM36, TMx_CF0A)

// Assert TM36_CF0B flag? (second capture event)
#define Timer_Get2ndCapture()       TM_GetSingleFlagStatus(TM36, TMx_CF0B)

// Timer_Corrected : The 2nd capture period minus the 1st capture period.
#define Timer_Corrected()           \
    TM36->STA.H[0] = 0xFFFF;        \
    TM36->CC0B.H[0] = (TM36->CC0B.H[0] - TM36->CC0A.H[0])

// Corrected the second capture period
#define Timer_GetDelta()            TM36->CC0A.H[0] - TM36->CC0B.H[0]

// Get the first capture period
#define Timer_GetHighCount()        TM36->CC0A.H[0]

// Determine whether (the first capture period) is greater than (the second capture period)
#define Timer_HmoreL()              TM36->CC0A.H[0] > TM36->CC0B.H[0]

// Config TM36 TRGI with Falling edge to reset TM36 counter.
#define Timer_LowEventResetCounter()                \
    TM_TRGICounter_Select(TM36, TRGI_ResetFalling); \
    TM_TRGIPrescaler_Select(TM36, TRGI_ResetFalling)

//#define Timer_HighEventResetCounter()              \
//    TM_TRGICounter_Select(TM36, TRGI_ResetRising); \
//    TM_TRGIPrescaler_Select(TM36, TRGI_ResetRising)



/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
void DHT_begin(void);
float DHT_convertCtoF(float c);
float DHT_convertFtoC(float f);
float DHT_readTemperature(boolean S);
float DHT_readHumidity(void); 
boolean DHT_read(void);



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



