/*!
 * @file        lin.h
 *
 * @brief       Header for main.c module
 *
 * @version     V1.0.0
 *
 * @date        2023-03-30
 *
 * @attention
 *
 *  Copyright (C) 2023 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 useful 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.
 */

/* Define to prevent recursive inclusion */
#ifndef LIN_H
#define LIN_H

#ifdef __cplusplus
extern "C" {
#endif

/* Includes */
#include "Board.h"

/** @addtogroup Examples
  @{
*/

/** @addtogroup USART_Examples
  @{
*/

/** @addtogroup USART_LIN_autosync
  @{
*/

/** @defgroup USART_LIN_autosync_INT_Macros INT_Macros
  @{
*/

#define LIN_AUTO_BAUDRATE_TIMEOUT_XMS 20

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

#define PARITY(A)   ((uint8_t)((uint32_t)((((( 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_t)((uint8_t)(PARITY((uint8_t)A)|(uint8_t)A)))

#define PARITY_FIELD(A) ((uint8_t)((uint8_t)(PARITY((uint8_t)A)|(uint8_t)A)))

#define ERROR_NONE             0x00000000U                         /*!< No error             */
#define ERROR_TIMEOUT          0x00000001U                         /*!< Timeout error        */

#define TIMEOUT_VALUE          0xFFFF
/**@} end of group USART_LIN_autosync_INT_Macros */

/** @defgroup USART_LIN_autosync_INT_Enumerations INT_Enumerations
  @{
*/

/**
* @brief    Lin state
*/
typedef 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
} Lin_StateType;
/**
 * @brief     The definition of the lin response type
 */
typedef enum
{
    LIN_IDLE = 0,
    LIN_RECEIVE = 1,
    LIN_SET = 2
} Lin_ResponseType;

/**@} end of group USART_LIN_autosync_INT_Enumerations */


/** @defgroup USART_LIN_autosync_INT_Structures INT_Structures
  @{
*/

typedef struct
{
    uint8_t     ID;         /*!< Specifies the id */
    uint8_t     data[8];    /*!< Specifies the data */
    uint8_t     CheckSum;   /*!< Specifies the check sum */
} Lin_MessageType;

typedef struct
{
    uint8_t id;
    uint8_t protected_id;
    uint8_t data_len;
    uint8_t data_dir;
}Lin_MsgType;

/**@} end of group USART_LIN_autosync_INT_Structures */

/** @defgroup USART_LIN_autosync_INT_Variables INT_Variables
  @{
*/
extern Lin_MessageType g_MasterSend;
extern Lin_MessageType g_MasterReceived;

extern volatile uint8_t g_MasterReceivedProces;
extern volatile uint8_t g_MasterReceiveDataProces;
extern volatile uint8_t g_MasterReceivedOverFlag;

extern Lin_MessageType g_SlaveSend;
extern Lin_MessageType g_SlaveReceived;

extern volatile uint8_t g_SlaveReceivedProces;
extern volatile uint8_t g_SlaveReceivedDataProces;
extern volatile uint8_t g_SlaveReceivedOverFlag;
extern uint8_t g_ResponseBuf[9];
extern uint8_t g_SendBuf[9];
extern volatile uint8_t g_frameIndex;
extern uint8_t* g_dataPtr;
extern volatile uint8_t g_pid;
extern volatile uint8_t g_currentId;
extern volatile uint8_t g_checkSum;
extern const Lin_MsgType g_linMsgCfgTable[3];
extern const uint8_t g_linMsgTblLen;

#ifdef LIN_AUTO_BAUDRATE_ENABLE
extern volatile uint32_t g_sysTick;
#endif

/**@} end of group USART_LIN_autosync_INT_Variables */

/** @defgroup USART_LIN_autosync_INT_Functions INT_Functions
  @{
*/
void Lin_MasterIsr(USART_T* UsartPtr);
void Lin_SlaveIsr(USART_T* UsartPtr);
void Lin_ErrorInterrupt_ProcessingCode(USART_T* UsartPtr);
void Lin_Init(void);
void Lin_MasterSendSlave(void);
void Lin_SendBreak(USART_T* UsartPtr);
uint32_t Lin_SendSyncSegment(USART_T* UsartPtr, uint32_t Timeout);
uint8_t Lin_CheckPid(uint8_t Id);
uint8_t Lin_ProcessParity(uint8_t Pid);
uint8_t Lin_Hw_CheckSum(uint8_t Pid, const uint8_t* BufferPtr);
void Lin_Hw_ProcessPid(uint8_t Pid, USART_T* UsartPtr);
uint32_t Lin_SendHead(USART_T* UsartPtr, Lin_MessageType LinMessage, uint32_t Timeout);
uint32_t Lin_SendAnswer(USART_T* UsartPtr, Lin_MessageType LinMessage, uint32_t Timeout);
uint8_t Lin_CheckSum(uint8_t id, const uint8_t* DataPtr);
uint32_t Lin_TxData(USART_T* UsartPtr, const uint8_t* DataPtr, uint32_t Timeout);
uint8_t Lin_SlaveReceivedProces(void);
void Lin_GetTxDataNotification(uint8_t FrameIdx, uint8_t* DataBufferPtr);
void Lin_PidReceivedNotification(uint8_t Pid, uint8_t FrameIndex);

#ifdef __cplusplus
}
#endif

#endif /* __LIN_H */

/**@} end of group USART_LIN_autosync_INT_Functions */
/**@} end of group USART_LIN_autosync */
/**@} end of group USART_Examples */
/**@} end of group Examples */
