/*!
* @file     Lin_Hw.h
*
* @version  1.0.0
*
* @brief    AUTOSAR Lin - Low level driver header file.
*           This file includes the function prototypes defined in the LIN low level driver for USART.
* @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 LIN_HW_H
#define LIN_HW_H

#include "Lin_Cfg.h"
#include "Platform_Types.h"
#include "Lin_GeneralTypes.h"
#include "Std_Types.h"
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup G32A10xx_StdPeriphDriver
  @{
*/

/** @defgroup LIN_Driver
  * @brief LIN driver modules
  @{
*/

/** @defgroup LIN_Macros
  @{
*/
/*******************************************************************************
                     VENDOR ID & AUTOSAR VERSION INFO
*******************************************************************************/
/** Vendor ID (vendorId) of the dedicated implementation of this module according to the AUTOSAR vendor list. */
#define LIN_HW_H_VENDOR_ID                     0x00C1U
/** Major version number of AUTOSAR release on which the appropriate implementation is based on. */
#define LIN_HW_H_AR_RELEASE_MAJOR_VERSION      0x04U
/** Minor version number of AUTOSAR release on which the appropriate implementation is based on. */
#define LIN_HW_H_AR_RELEASE_MINOR_VERSION      0x04U
/** Revision version number of AUTOSAR release on which the appropriate implementation is based on. */
#define LIN_HW_H_AR_RELEASE_REVISION_VERSION   0x00U
/** Major version number of the vendor specific implementation of the module. The numbering is vendor specific. */
#define LIN_HW_H_SW_MAJOR_VERSION              0x01U
/** Minor version number of the vendor specific implementation of the module. The numbering is vendor specific. */
#define LIN_HW_H_SW_MINOR_VERSION              0x00U
/** Patch level version number of the vendor specific implementation of the module. The numbering is vendor specific. */
#define LIN_HW_H_SW_PATCH_VERSION              0x00U

/*******************************************************************************
                              MACRO DEFINITION
*******************************************************************************/
/** LIN bit length */
#define LIN_HW_BIT_LENGTH32(baudrate) (((uint32)(1000000U))/((uint32)(baudrate)))

/** Maximum data length */
#define LIN_HW_MAXIMUM_DATA_LENGTH ((uint8)LIN_SDU_MAX_LEN)
/** Maximum Buffer Length (Break(1), Sync(1), Pid(1), Data bytes and Checksum(1)) */
#define LIN_HW_MAXIMUM_BUFFER_LENGTH ((uint8)LIN_SDU_MAX_LEN+(uint8)3U)

/** Sync byte */
#define LIN_HW_SYNC_BYTE ((uint8)0x55U)

#define BITT(A,B)  ((uint32)(((uint32)(A) >> (uint32)(B)) & 1UL))

#define PARITY(A)   ((uint8)((uint32)((((( BITT((A),0U) ^ BITT((A),1U) ^ BITT((A),2U) ^ BITT((A),4U))) & 1UL) << 6U) | \
                          (((~( BITT((A),1U) ^ BITT((A),3U) ^ BITT((A),4U) ^ BITT((A),5U))) & 1UL) << 7U))))
#define PARITY_FIELD(A) ((uint8)((uint8)(PARITY((uint8)A)|(uint8)A)))
/**@} end of group LIN_Macros */
/*******************************************************************************
                            ENUMERATION DEFINITION
*******************************************************************************/
/** @defgroup LIN_Enumerations
  @{
*/
/**
* @brief    Lin state
*/
enum
{
    IDLE = 0x00,                //!< IDLE state
    SEND_BREAK = 0x01,          //!< Send break field state
    SEND_PID = 0x02,            //!< send PID state
    RECV_SYN = 0x03,            //!< receive synchronize state
    RECV_PID = 0x04,            //!< receive PID state
    IGNORE_DATA = 0x05,         //!< ignore data state
    RECV_DATA = 0x06,           //!< receive data state
    SEND_DATA = 0x07,           //!< send data state
    SEND_DATA_COMPLETED = 0x08, //!< send data completed state
    PROC_CALLBACK = 0x09,       //!< proceduce callback state
    SLEEP_MODE = 0x0A,          //!< sleep mode state
    UNINIT = 0xFF               //!< uninitialize state
};

/**
* @brief    Master demand Diagnostic Frame ID
*/
enum
{
    USART_MASTER_DEMAND_DIAGNOSTIC_ID  = ((uint8)0x3CU),
    USART_SLAVE_RESPOND_DIAGNOSTIC_ID  = ((uint8)0x3DU),
    USART_MASTER_DEMAND_DIAGNOSTIC_PID = ((uint8)0x3CU),
    USART_SLAVE_RESPOND_DIAGNOSTIC_PID = ((uint8)0x7DU)
};
  
/**
* @brief    The location of Break byte in the BytesToSend buffer
*/
enum
{
    USART_SYNCH_BYTE_POSITION = ((uint8)0U),
    USART_PID_BYTE_POSITION   = ((uint8)1U),
    USART_FRAME_ID_MASK       = ((uint32)0x3FU),
    USART_DATA_POSITION       = ((uint8)2U)
};

enum
{
    USART_255_SLEEP_DATA = ((uint8)255U), //!< Sleep command frame: 0xFF data
    USART_0_SLEEP_DATA   = ((uint8)0U)    //!< Sleep command frame: 0x00 data
};

/**
 * @brief     The definition of the lin response type
 */
typedef enum
{
    LIN_IDLE = 0,
    LIN_RECEIVE = 1,
    LIN_SET = 2
} Lin_ResponseType;
/**@} end of group LIN_Enumerations */

/*******************************************************************************
                           GLOBAL VARIABLE DECLARATION
*******************************************************************************/
/** @defgroup LIN_Variable
  @{
*/
#define LIN_START_SEC_VAR_NO_INIT_8
#include "Lin_MemMap.h"

extern volatile VAR(uint8, LIN_VAR) g_state;
extern volatile VAR(uint8, LIN_VAR) g_currentId;
extern volatile VAR(uint8, LIN_VAR) g_frameIndex;
extern volatile VAR(uint8, LIN_VAR) g_checkSum;
extern volatile VAR(uint16, LIN_VAR) g_idleTimeoutCnt; 
extern volatile VAR(uint16, LIN_VAR) g_respFrameTimeoutCnt;
extern P2VAR(uint8, AUTOMATIC, LIN_VAR) g_dataPtr;

#define LIN_STOP_SEC_VAR_NO_INIT_8
#include "Lin_MemMap.h"

#define LIN_START_SEC_VAR_INIT_8
#include "Lin_MemMap.h"

extern VAR(uint8, LIN_VAR) g_responseBuf[9];
extern VAR(uint8, LIN_VAR) g_sendBuf[9];
extern volatile VAR(uint8, LIN_VAR) g_cntByte;
extern volatile VAR(uint8, LIN_VAR) g_pid;
extern volatile VAR(uint16, LIN_VAR) g_receiveOnceFlg;
#define LIN_STOP_SEC_VAR_INIT_8
#include "Lin_MemMap.h"

/**@} end of group LIN_Variable */
/*******************************************************************************
                           FUNCTION DECLARATION
*******************************************************************************/
/** @defgroup LIN_Fuctions
  @{
*/
#define LIN_START_SEC_CODE
#include "Lin_MemMap.h"

FUNC (Lin_StatusType, LIN_CODE) Lin_Hw_GetStatus(CONST(uint8, AUTOMATIC) ChannelID, 
                                                       P2VAR(uint8, AUTOMATIC, LIN_APPL_DATA) linSduPointer);
FUNC (void, LIN_CODE) Lin_Hw_WakeupChannel(CONST(uint8, AUTOMATIC) ChannelID);
FUNC (void, LIN_CODE) Lin_Hw_SendWakeUpFrame(CONST(uint8, AUTOMATIC) ChannelID);
FUNC (Std_ReturnType, LIN_CODE) Lin_Hw_GoToSleepStatus(CONST(uint8, AUTOMATIC) ChannelID);
FUNC (Std_ReturnType, LIN_CODE) Lin_Hw_SendGoToSleepFrame(CONST(uint8, AUTOMATIC) ChannelID);
FUNC (void, LIN_CODE) Lin_Hw_SendFrameResponse(CONST(uint8, AUTOMATIC) ChannelID, 
                                                   P2CONST(Lin_PduType, AUTOMATIC, LIN_APPL_CONST) pduInfoPointer);
FUNC (Std_ReturnType, LIN_CODE) Lin_Hw_SendFrameHeader(CONST(uint8, AUTOMATIC) ChannelID, 
                                                           P2CONST(Lin_PduType, AUTOMATIC, LIN_APPL_CONST) pduInfoPointer);
FUNC (void, LIN_CODE) Lin_Hw_InitLinChannel(CONST(uint8, AUTOMATIC) ChannelID);
FUNC (Std_ReturnType, LIN_CODE) Lin_Hw_CheckChannelWakeup(CONST(uint8, AUTOMATIC) ChannelID);
FUNC (void, LIN_CODE) Lin_Hw_ErrorInterrupt_ProcessingCode(CONST(uint8, AUTOMATIC) usartChannelID);
FUNC (void, LIN_CODE) Lin_Hw_TxRxInterrupt_ProcessingCode(CONST(uint8, AUTOMATIC) usartChannelID);

#if defined(LIN_USART2)
ISR(USART2_IRQHandler);
#endif

#if defined(LIN_USART1)
ISR(USART1_IRQHandler);
#endif

#define LIN_STOP_SEC_CODE
#include "Lin_MemMap.h"

/**@} end of group LIN_Fuctions */
#ifdef __cplusplus
}
#endif 
#endif
/**@} end of group LIN_Driver */
/**@} end of group G32A10xx_StdPeriphDriver */
