/*!
* @file     CDD_Usart.h
*
* @version  1.0.0
*
* @brief    Usart driver header file
*
* @attention
*
* Project Name      : AUTOSAR MCAL
*
* Platform          : Arm
*
* Autosar Standard  : Classic Platform 4.4.0
*
* Compiled Version  : G32A10xx_MCAL_1_0_0_01-Otc-25
*
* Copyright (C) 2026 Geehy Semiconductor
*
* You may not use this file except in compliance with the
* GEEHY COPYRIGHT NOTICE (Geehy Semiconductor Software License Agreement).
*
* The program is only for reference, which is distributed in the hope
* that it will be usefull and instructional for customers to develop
* their software. Unless required by applicable law or agreed to in
* writing, the program is distributed on an "AS IS" BASIS, WITHOUT
* ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
* See the Geehy Semiconductor Software License Agreement for the governing permissions
* and limitations under the License.
*/

#ifndef CDD_USART_H
#define CDD_USART_H

#ifdef __cplusplus
extern "C" {
#endif

#include "stdio.h"
#include "Mcal.h"
#include "StdRegMacros.h"
#include "CDD_Usart_Cfg.h"

#if (STD_ON == USART_DMA_SUPPORT)
#include "Pdl_DmaTypes.h"
#include "Pdl_Types.h"
#endif

/** @addtogroup G32A10xx_StdPeriphDriver
  @{
*/

/** @defgroup USART_Driver
  @{
*/

/** @defgroup USART_Macros
  @{
*/
/*******************************************************************************
                    VENDOR ID & AUTOSAR VERSION INFO
*******************************************************************************/
/* Vendor ID (vendorId) of the dedicated implementation of this module according to the AUTOSAR vendor list. */
#define CDD_USART_H_VENDOR_ID                     0x00C1U
/* Module ID of this module, as defined in the BSW Module List. */
#define CDD_USART_H_MODULE_ID                     0x00FFU
/* Major version number of AUTOSAR release on which the appropriate implementation is based on. */
#define CDD_USART_H_AR_RELEASE_MAJOR_VERSION      0x04U
/* Minor version number of AUTOSAR release on which the appropriate implementation is based on. */
#define CDD_USART_H_AR_RELEASE_MINOR_VERSION      0x04U
/* Revision version number of AUTOSAR release on which the appropriate implementation is based on. */
#define CDD_USART_H_AR_RELEASE_REVISION_VERSION   0x00U
/* Major version number of the vendor specific implementation of the module. The numbering is vendor specific. */
#define CDD_USART_H_SW_MAJOR_VERSION              0x01U
/* Minor version number of the vendor specific implementation of the module. The numbering is vendor specific. */
#define CDD_USART_H_SW_MINOR_VERSION              0x00U
/* Patch level version number of the vendor specific implementation of the module. The numbering is vendor specific. */
#define CDD_USART_H_SW_PATCH_VERSION              0x00U

/*******************************************************************************
                                ERROR CODES
*******************************************************************************/
/** API service called with NULL pointer */
#define USART_E_PARAM_POINTER           ((uint8)0x0AU)

/** Invalid state transition for the current state */
#define USART_E_STATE_TRANSITION        ((uint8)0x0BU)

/** Timeout caused by hardware error */
#define USART_E_TIMEOUT                 ((uint8)0x0CU)

/** Module not initialized */
#define USART_E_UNINIT                  ((uint8)0x0DU)

/*******************************************************************************
                            API Service ID List
*******************************************************************************/
/** Instance identification ID for AUTOSAR module  */
#define USART_INSTANCE_MODULE_ID        ((uint8)0x00U)

/** Usart_GetVersionInfo service id */
#define USART_GETVERSIONINFO_SVC_ID     ((uint8)0x01U)

/** Usart_Init service id */
#define USART_INIT_SVC_ID               ((uint8)0x02U)

/** USART_TxDataPolling service id */
#define USART_TXDATAPOLLING_SVC_ID      ((uint8)0x03U)

/** Usart_TxData service id */
#define USART_TXDATA_SVC_ID             ((uint8)0x04U)

/** Usart_RxDataPolling service id */
#define USART_RXDATAPOLLING_SVC_ID      ((uint8)0x05U)

/** Usart_RxData service id */
#define USART_RXDATA_SVC_ID             ((uint8)0x06U)

/** Usart_GetStatus service id */
#define USART_GETSTATUS_SVC_ID          ((uint8)0x07U)

/*******************************************************************************
                            MACRO DEFINITION
*******************************************************************************/
/** Number of instances of the USART module */
#define USART_INSTANCE_CNT              (2U)

/** usart1 tx addr */
#define USART1_TX_DMA_ADDR              0x40013828U

/** usart2 tx addr */
#define USART2_TX_DMA_ADDR              0x40004428U

/** usart1 rx addr */
#define USART1_RX_DMA_ADDR              0x40013824U

/** usart2 rx addr */
#define USART2_RX_DMA_ADDR              0x40004424U

/**@} end of group USART_Macros */
/*******************************************************************************
                            ENUM DEFINITION
*******************************************************************************/
/** @defgroup USART_Enumerations
  @{
*/

/**
* @brief   USART ID
*/
typedef enum
{
    USART1_ID = 0,
    USART2_ID = 1
} Usart_UsartIdType;

/**
* @brief   USART Word Length define
*/
typedef enum
{
    USART_WORD_LEN_8B = 0,      //!< 8-bit data length
    USART_WORD_LEN_9B = BIT12   //!< 9-bit data length
} Usart_WordLenType;

/**
* @brief   USART Stop bits define
*/
typedef enum
{
    USART_STOP_BIT_1    = 0,             //!< 1-bit stop bit
    USART_STOP_BIT_2    = BIT13,         //!< 2-bit stop bit
    USART_STOP_BIT_1_5  = BIT12 | BIT13  //!< 1.5-bit stop bit
} Usart_StopBitsType;

/**
* @brief   USART Parity define
*/
typedef enum
{
    USART_PARITY_NONE   = 0,            //!< Disable parity control
    USART_PARITY_EVEN   = BIT10,        //!< Enable even parity control
    USART_PARITY_ODD    = BIT10 | BIT9  //!< Enable odd parity control
} Usart_ParityType;

/**
* @brief   USART mode define
*/
typedef enum
{
    USART_MODE_NONE     = 0,           //!< none
    USART_MODE_RX       = BIT2,        //!< Enable USART Receive mode
    USART_MODE_TX       = BIT3,        //!< Enable USART transmit mode
    USART_MODE_TX_RX    = BIT2 | BIT3  //!< Enable USART receive and transmit mode
} Usart_DirectionType;

/**
* @brief   USART hardware flow control define
*/
typedef enum
{
    USART_FLOW_CTRL_NONE    = 0,           //!< Disable hardware flow control
    USART_FLOW_CTRL_RTS     = BIT8,        //!< Enable RTS hardware flow control
    USART_FLOW_CTRL_CTS     = BIT9,        //!< Enable CTS hardware flow control
    USART_FLOW_CTRL_RTS_CTS = BIT8 | BIT9  //!< Enable RTS and CTS hardware flow control
} Usart_HwFlowCtrlType;

/**
* @brief   USART DMA requests
*/
typedef enum
{
    USART_DMA_REQUEST_RX    = BIT6,  //!< USART DMA receive request
    USART_DMA_REQUEST_TX    = BIT7   //!< USART DMA transmit request
} Usart_DmaRequestType;

/**
* @brief   USART DMA reception error
*/
typedef enum
{
    USART_DMA_RXERR_ENABLE  = ((uint8)0),  //!< USART DMA reception error enable
    USART_DMA_RXERR_DISABLE = ((uint8)1)   //!< USART DMA reception error disable
} Usart_DmaRxerrType;

/**
* @brief    USART flag definition
*/
typedef enum
{
    USART_FLAG_RXENACKF    = ((uint32)0x00400000),  //!< Receive Enable Acknowledge Flag
    USART_FLAG_TXENACKF    = ((uint32)0x00200000),  //!< Transmit Enable Acknowledge Flag
    USART_FLAG_SBF         = ((uint32)0x00040000),  //!< Send Break flag
    USART_FLAG_CMF         = ((uint32)0X00020000),  //!< Character match flag
    USART_FLAG_BUSY        = ((uint32)0X00010000),  //!< Busy flag
    USART_FLAG_ABRTF       = ((uint32)0X00008000),  //!< Auto baud rate flag
    USART_FLAG_ABRTE       = ((uint32)0X00004000),  //!< Auto baud rate error flag
    USART_FLAG_RXTOF       = ((uint32)0X00000800),  //!< Receive time out flag
    USART_FLAG_CTSF        = ((uint32)0X00000400),  //!< CTS Change flag
    USART_FLAG_CTSIF       = ((uint32)0X00000200),  //!< CTS interrupt flag
    USART_FLAG_TXBE        = ((uint32)0X00000080),  //!< Transmit data register empty flag
    USART_FLAG_TXC         = ((uint32)0X00000040),  //!< Transmission Complete flag
    USART_FLAG_RXBNE       = ((uint32)0X00000020),  //!< Receive data buffer not empty flag
    USART_FLAG_IDLEF       = ((uint32)0X00000010),  //!< Idle Line detection flag
    USART_FLAG_OVRE        = ((uint32)0X00000008),  //!< OverRun Error flag
    USART_FLAG_NEF         = ((uint32)0X00000004),  //!< Noise Error flag
    USART_FLAG_FEF         = ((uint32)0X00000002),  //!< Framing Error flag
    USART_FLAG_PEF         = ((uint32)0X00000001)   //!< Parity Error flag
} Usart_FlagType;

/**
* @brief   USART interrupts source
*/
typedef enum
{
    USART_INT_CMIE         = ((uint32)0x00004000),  //!< Character match interrupt
    USART_INT_RXTOIE       = ((uint32)0x04000000),  //!< Receive time out interrupt
    USART_INT_CTSIE        = ((uint32)0x00000400),  //!< CTS change interrupt
    USART_INT_TXBEIE       = ((uint32)0x00000080),  //!< Tansmit Data Register empty interrupt
    USART_INT_TXCIE        = ((uint32)0x00000040),  //!< Transmission complete interrupt
    USART_INT_RXBNEIE      = ((uint32)0x00000020),  //!< Receive Data buffer not empty interrupt
    USART_INT_IDLEIE       = ((uint32)0x00000010),  //!< Idle line detection interrupt
    USART_INT_PEIE         = ((uint32)0x00000100),  //!< Parity Error interrupt
    USART_INT_ERRIE        = ((uint32)0x00000001)   //!< Error interrupt
} Usart_IntType;

/**
* @brief   USART Interrupt flag definition
*/
typedef enum
{
    USART_INT_FLAG_CMF     = ((uint32)0X00020000),  //!< Character match flag
    USART_INT_FLAG_RXTOF   = ((uint32)0X00000800),  //!< Receive time out flag
    USART_INT_FLAG_CTSIF   = ((uint32)0X00000200),  //!< CTS interrupt flag
    USART_INT_FLAG_TXBE    = ((uint32)0X00000080),  //!< Transmit data register empty flag
    USART_INT_FLAG_TXC     = ((uint32)0X00000040),  //!< Transmission Complete flag
    USART_INT_FLAG_RXBNE   = ((uint32)0X00000020),  //!< Receive data buffer not empty flag
    USART_INT_FLAG_IDLE    = ((uint32)0X00000010),  //!< Idle Line detection flag
    USART_INT_FLAG_OVRE    = ((uint32)0X00000008),  //!< OverRun Error flag
    USART_INT_FLAG_NE      = ((uint32)0X00000004),  //!< Noise Error flag
    USART_INT_FLAG_FE      = ((uint32)0X00000002),  //!< Framing Error flag
    USART_INT_FLAG_PE      = ((uint32)0X00000001)   //!< Parity Error flag
} Usart_IntFlagType;


/* USART transfer type */
typedef enum
{
    USART_USE_DMA = 0U,         //!< The driver will use DMA to perform UART transfer
    USART_USE_INTERRUPTS = 1U   //!< The driver will use interrupts to perform UART transfer
} Usart_TransferType;


/* USART transfer type */
typedef enum
{
    USART_FULL_DUPLEX_ASYN = 0U, //!< Full-duplex asynchronous  
    USART_HALF_DUPLEX = 1U,      //!< Half-duplex  
    USART_FULL_DUPLEX_SYN = 2U   //!< Full-duplex synchronous  
} Usart_AppModeSelectType;


/* USART clock polarity config */
typedef enum
{
    USART_CPOL_LOW = 0U, //!< cpol low  
    USART_CPOL_HIGH = 1U //!< cpol high
} Usart_ClockPolType;


/* USART clock polarity config */
typedef enum
{
    USART_CPHA_1EDGE = 0U, //!< 1 phase  
    USART_CPHA_2EDGE = 1U  //!< 2 phase  
} Usart_ClockPhaType;


/*!
* @brief   Error codes
* @details Error codes will be a unified enumeration which contains all error
*          codes (common and specific). There will be separate spaces, each of
*          256 positions, allocated for each functionality.
*/
typedef enum
{
    /* Generic error codes */
    STATUS_USART_SUCCESS        = 0x0000U,  //!< Generic success status
    STATUS_USART_ERROR          = 0x0001U,  //!< Generic failure status
    STATUS_USART_BUSY           = 0x0002U,  //!< Generic busy status
    STATUS_USART_TIMEOUT        = 0x0003U,  //!< Generic timeout status
    STATUS_USART_UNSUPPORTED    = 0x0004U,  //!< Generic unsupported status

    STATUS_USART_ABORTED        = 0x0500U,  //!< A transfer was aborted
    STATUS_USART_RX_OVERRUN     = 0x0501U,  //!< RX overrun error
    STATUS_USART_TX_UNDERRUN    = 0x0502U,  //!< TX underrun error
    STATUS_USART_NOISE_ERROR    = 0x0503U,  //!< Noise error
    STATUS_USART_PARITY_ERROR   = 0x0504U,  //!< Parity error
    STATUS_USART_FRAMING_ERROR  = 0x0505U   //!< Framing error
} Usart_StatusType;

/**@} end of group USART_Enumerations */
/*******************************************************************************
                            STRUCT DEFINITION
*******************************************************************************/
/** @defgroup USART_Structure
  @{
*/

/**
* @brief   USART Config struct definition
*/
typedef struct
{
    Usart_UsartIdType           usartId;         //!< usart channel
    Usart_TransferType          transferType;    //!< Type of USART transfer (interrupt/dma based)
    Usart_AppModeSelectType     modeSelect;      //!< mode select
    
    uint32                      baudRate;        //!< Specifies the baud rate
    Usart_WordLenType           wordLength;      //!< Specifies the word length
    Usart_StopBitsType          stopBits;        //!< Specifies the stop bits
    Usart_ParityType            parity;          //!< Specifies the parity
    Usart_DirectionType         mode;            //!< Specifies the mode
    Usart_HwFlowCtrlType        hardwareFlowCtrl;
    
    uint8                     rxDmaChannel;    //!< Channel number for DMA rx channel
    uint8                     txDmaChannel;    //!< Channel number for DMA tx channel
} Usart_ConfigType;




typedef struct
{
    Usart_ClockPolType clkPol;
    Usart_ClockPhaType clkPha;
    boolean lastBitOutput;
} Usart_SyncConfigType;

/**
* @brief   USART internal state
*/
typedef struct
{ 
    Usart_UsartIdType       usartId;
    Usart_DirectionType     mode;       //!< Specifies the mode
    Usart_AppModeSelectType modeSelect;  //!< mode select
    
    uint8 rxDmaChannel;   //!< DMA channel number for DMA-based rx
    uint8 txDmaChannel;   //!< DMA channel number for DMA-based tx
    
    volatile Usart_StatusType rxStatus;     //!< Status of last driver receive operation
    volatile Usart_StatusType txStatus;     //!< Status of last driver transmit operation
    
    volatile boolean rxBusy;    //!< True if there is an active receive
    volatile boolean txBusy;    //!< True if there is an active transmit
    
    volatile boolean rxBlocking;    //!< True if receive is blocking transaction
    volatile boolean txBlocking;    //!< True if transmit is blocking transaction
    
    volatile uint32 rxLen;    //!< The remaining number of bytes to be received
    volatile uint32 txLen;    //!< The remaining number of bytes to be transmitted
    
    uint16 *rxBuffer;             //!< The buffer of received data
    const uint8 *txBuffer;        //!< The buffer of data being sent
        
    Usart_TransferType transferType;    //!< Type of USART transfer (interrupt/dma based)
    Usart_WordLenType wordLength;   //!< Number of bits in a char (8/9/10)
    Usart_StopBitsType  stopBits;   //!< Specifies the stop bits
    Usart_ParityType    parity; //!< Specifies the parity
} Usart_StateType;

/**@} end of group USART_Structure */
/*******************************************************************************
                             CONSTANT DEFINITION
*******************************************************************************/
/** @defgroup USART_Variable
  @{
*/
extern Usart_StateType g_lpuartStatus[USART_INSTANCE_CNT];
extern const Usart_ConfigType g_usartConfg[USART_CHANNEL_NUM];
extern const Usart_SyncConfigType g_usartSyncConfg[USART_CHANNEL_NUM];

/**@} end of group USART_Variable */
/*******************************************************************************
                            FUNCTION DECLARATION
*******************************************************************************/
/** @defgroup USART_Fuctions
  @{
*/

FUNC(void, USART_CODE) Usart_Init(P2CONST(Usart_ConfigType, AUTOMATIC, USART_APPL_CONST) usartConfig);

FUNC(Usart_StatusType, USART_CODE) Usart_TxData(Usart_UsartIdType usartId,
                                                const uint8 *txBuf,
                                                uint32 txLen);

FUNC(Usart_StatusType, USART_CODE) Usart_RxData(Usart_UsartIdType usartId,
                                                uint16 *rxBuf,
                                                uint32 rxLen);
                                      
FUNC(Usart_StatusType, USART_CODE) Usart_TxDataPolling(Usart_UsartIdType usartId, 
                                                const uint8 *txBuf, 
                                                uint32 txLen);

FUNC(Usart_StatusType, USART_CODE) Usart_RxDataPolling(Usart_UsartIdType usartId,
                                                       uint16 *rxBuf,
                                                       uint32 rxLen);
FUNC(Usart_StatusType, USART_CODE) Usart_GetStatus(Usart_UsartIdType usartId, 
                                                   Usart_DirectionType dir, 
                                                   uint32 *bytesRemain);
FUNC(int32, USART_CODE) Usart_PutRedefinition(Usart_UsartIdType usartId, 
                                               const int32 * ch);
FUNC(void, USART_CODE) Usart_GetVersionInfo(Std_VersionInfoType * VersionInfo);

/**@} end of group USART_Fuctions */

#ifdef __cplusplus
}
#endif

#endif /* __USART_DRV_H */

/**@} end of group USART_Driver */
/**@} end of group G32A10xx_StdPeriphDriver */
