/******************************************************************************
 * $Revision: 423 $
 * $Date:: 2017-04-07 16:03:30 +0900#$
 *****************************************************************************/
/* __DISCLAIMER_START__                                                      */
/******************************************************************************
* (c)2017, Cypress Semiconductor Corporation
* or a subsidiary of Cypress Semiconductor Corporation. All rights
* reserved.
*
* This software, including source code, documentation and related
* materials ( "Software" ), is owned by Cypress Semiconductor
* Corporation or one of its subsidiaries ( "Cypress" ) and is protected by
* and subject to worldwide patent protection (United States and foreign),
* United States copyright laws and international treaty provisions.
* Therefore, you may use this Software only as provided in the license
* agreement accompanying the software package from which you
* obtained this Software ( "EULA" ).
*
* If no EULA applies, Cypress hereby grants you a personal, nonexclusive,
* non-transferable license to copy, modify, and compile the
* Software source code solely for use in connection with Cypress' s
* integrated circuit products. Any reproduction, modification, translation,
* compilation, or representation of this Software except as specified
* above is prohibited without the express written permission of Cypress.
*
* Disclaimer: THIS SOFTWARE IS PROVIDED AS-IS, WITH NO
* WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING,
* BUT NOT LIMITED TO, NONINFRINGEMENT, IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE. Cypress reserves the right to make
* changes to the Software without notice. Cypress does not assume any
* liability arising out of the application or use of the Software or any
* product or circuit described in the Software. Cypress does not
* authorize its products for use in any products where a malfunction or
* failure of the Cypress product may reasonably be expected to result in
* significant property damage, injury or death ( "High Risk Product" ). By
* including Cypress' s product in a High Risk Product, the manufacturer
* of such system or application assumes all risk of such use and in doing
* so agrees to indemnify Cypress against all liability.
******************************************************************************/
/* __DISCLAIMER_END__                                                        */
/*****************************************************************************/
/** \file mfs_lin.h
 **
 ** Headerfile for LIN functions
 **
 ** History:
 **   - 2014-07-02  0.01  HS  Initial version for Traveo
 *****************************************************************************/

#ifndef __MFS_LIN_H__
#define __MFS_LIN_H__

/*****************************************************************************/
/* Include files                                                             */
/*****************************************************************************/
#include "base_types.h"

/* C binding of definitions if building with C++ compiler */
#ifdef __cplusplus
extern "C"
{
#endif

/**
 *****************************************************************************
 ** \defgroup LinGroup Local Interconnect Network (LIN)
 **
 ** \brief This section describes the interface for the Local Interconnect Network.
 **
 ** Provided functions of LIN module:
 **
 **- Mfs_Lin_Init()
 **- Mfs_Lin_SetAutoHeader()
 **- Mfs_Lin_WriteData()
 **- Mfs_Lin_ReadData()
 **- Mfs_Lin_GetReceivedId()
 **- Mfs_Lin_EnableRx()
 **- Mfs_Lin_DisableRx()
 **- Mfs_Lin_EnableTx()
 **- Mfs_Lin_DisableTx()
 **- Mfs_Lin_GetReloadValue()
 **- Mfs_Lin_GetBaudrateAdjustmentFlag()
 **
 ** Mfs_Lin_Init() must be used for activation and setup of an LIN channel. All
 ** LIN connection related parameters can be set with parameter
 ** pstcConfig of type #stc_lin_config_t.
 **
 ** Mfs_Lin_SetAutoHeader() is used to start auto header transmission by master.
 ** Mfs_Lin_WriteData() is used to send response data. Sending of the data will
 ** start immediately.
 ** Mfs_Lin_ReadData() is used to get received response data.This function return
 ** last reception data set.
 ** Mfs_Lin_GetReceivedId() is used to get received ID.
 ** Mfs_Lin_EnableRx(), Mfs_Lin_DisableRx(), Mfs_Lin_EnableTx(), Mfs_Lin_DisableTx() are
 ** used to enable/disable Tx/Rx.
 **
 ** Mfs_Lin_GetReloadValue() is used to get conversion data to BGR reload value from
 ** data rate. If you want to calculate u16BgrUpperLimit or u16BgrLowerLimit setting,
 ** use this function with desired baud rate limit.
 ** At first, call Mfs_Lin_GetReloadValue() with a baud rate and Mfs_Lin_GetReloadValue() return
 ** a conversion data to BGR reload value. Then, set BGR reload value to u16BgrUpperLimit
 ** or u16BgrLowerLimit.
 **
 ** Mfs_Lin_GetBaudrateAdjustmentFlag() can be used to get the result of auto baud rate
 ** adjustment.
 **
 ** \note At this software, following settings are fixed:
 **       - Use assist mode and HW FIFO. Manual mode is not supported.
 **       - Auto baud rate adjustment is always enabled.
 **       - External clock input is not supported.
 **       - Reception and Transmission interrupt are not used.
 **         All events are handled in status interrupt.
 *****************************************************************************/
/** @{ */


/*****************************************************************************/
/* Global pre-processor symbols/macros ('#define')                           */
/*****************************************************************************/
/** Maximum value of BGR */
#define LIN_BGR_MAX (0x7FFF)
/** Minimum value of BGR */
#define LIN_BGR_MIN (0x3)
/** Maximum ID */
#define LIN_ID_MAX (0x3F)
/** Maximum data length */
#define LIN_DATA_LENGTH_MAX (8)
/** Minimum data length */
#define LIN_DATA_LENGTH_MIN (0)

/** LIN ch0 */
#define LIN0_Type   ((pstc_lin_type_t)&CPG_MFS00_LIN)
/** LIN ch1 */
#define LIN1_Type   ((pstc_lin_type_t)&CPG_MFS01_LIN)
/** LIN ch2 */
#define LIN2_Type   ((pstc_lin_type_t)&CPG_MFS02_LIN)
/** LIN ch3 */
#define LIN3_Type   ((pstc_lin_type_t)&CPG_MFS03_LIN)
/** LIN ch4 */
#define LIN4_Type   ((pstc_lin_type_t)&CPG_MFS04_LIN)
/** LIN ch5 */
#define LIN5_Type   ((pstc_lin_type_t)&CPG_MFS05_LIN)
/** LIN ch6 */
#define LIN6_Type   ((pstc_lin_type_t)&CPG_MFS06_LIN)
/** LIN ch7 */
#define LIN7_Type   ((pstc_lin_type_t)&CPG_MFS07_LIN)
/** LIN ch8 */
#define LIN8_Type   ((pstc_lin_type_t)&CPG_MFS08_LIN)
/** LIN ch9 */
#define LIN9_Type   ((pstc_lin_type_t)&CPG_MFS09_LIN)
/** LIN ch10 */
#define LIN10_Type   ((pstc_lin_type_t)&CPG_MFS10_LIN)
/** LIN ch11 */
#define LIN11_Type   ((pstc_lin_type_t)&CPG_MFS11_LIN)

/*****************************************************************************/
/* Global type definitions ('typedef')                                       */
/*****************************************************************************/
/**
 *****************************************************************************
 ** \brief LIN Unit Type
 *****************************************************************************/
typedef  volatile stc_cpg_mfsn_lin_t*  pstc_lin_type_t;

/**
 *****************************************************************************
 ** \brief LIN interrupt trigger
 **
 ** Indicates interrupt factors which triggered interrupt.
 *****************************************************************************/
typedef union un_lin_interrupt_trigger
{
    uint8_t u8Byte;
    struct {
        uint8_t DetectBreak         : 1;    /*!< Break field detection */
        uint8_t DetectError         : 1;    /*!< Error detection */
        uint8_t CompleteAutoHeader  : 1;    /*!< Auto header completion */
        uint8_t CompleteChecksum    : 1;    /*!< Checksum calculation completion */
        uint8_t                     : 4;
    } stcBits;
} un_lin_interrupt_trigger_t;

/**
 *****************************************************************************
 ** \brief LIN detected error
 **
 ** Indicates detected error.
 **
 ** \note: In auto baud rate adjustment mode, SyncDataError does not occur.
 **
 *****************************************************************************/
typedef union un_lin_detected_error
{
    uint8_t u8Byte;
    struct {
        uint8_t BusError            : 1;    /*!< Bus error */
        uint8_t ChecksumError       : 1;    /*!< Checksum error */
        uint8_t IdParityError       : 1;    /*!< ID parity error */
        uint8_t FramingError        : 1;    /*!< Framing error */
        uint8_t OverunError         : 1;    /*!< Overrun error */
        uint8_t                     : 3;
    } stcBits;
} un_lin_detected_error_t;

/**
 *****************************************************************************
 ** \brief Callback function type for LIN status callback.
 **
 ** \param [in] stcIntTrigger       List of factors which triggered interrupt.
 **                                 See #un_lin_interrupt_trigger_t
 ** \param [in] stcDetectedError    List of detected errors.
 **                                 See #un_lin_detected_error_t
 *****************************************************************************/
typedef void (*lin_status_cb_func_ptr_t)(un_lin_interrupt_trigger_t stcIntTrigger,
                                         un_lin_detected_error_t stcDetectedError);

/**
 *****************************************************************************
 ** \brief LIN break field lenght
 **
 ** This configuration is effective only when corresponding channel = master mode.
 *****************************************************************************/
typedef enum en_lin_break_field_length{
    LinBreakFieldLength13bits = 0,      /*!< 13-bit length */
    LinBreakFieldLength14bits = 1,      /*!< 14-bit length */
    LinBreakFieldLength15bits = 2,      /*!< 15-bit length */
    LinBreakFieldLength16bits = 3,      /*!< 16-bit length */
    LinBreakFieldLength17bits = 4,      /*!< 17-bit length */
    LinBreakFieldLength18bits = 5,      /*!< 18-bit length */
    LinBreakFieldLength19bits = 6,      /*!< 19-bit length */
    LinBreakFieldLength20bits = 7       /*!< 20-bit length */
}en_lin_break_field_length_t;

/**
 *****************************************************************************
 ** \brief LIN break delimiter length
 **
 ** This configuration is effective only when corresponding channel = master mode.
 *****************************************************************************/
typedef enum en_lin_break_delimiter_length{
    LinBreakDelimiterLength1bits = 0,   /*!< 1-bit length */
    LinBreakDelimiterLength2bits = 1,   /*!< 2-bit length */
    LinBreakDelimiterLength3bits = 2,   /*!< 3-bit length */
    LinBreakDelimiterLength4bits = 3,   /*!< 4-bit length */
}en_lin_break_delimiter_length_t;


/**
 *****************************************************************************
 ** \brief Stop bit selection.
 **
 *****************************************************************************/
typedef enum en_lin_stopbit
{
    LinOneStopBit   = 0,    /*!< 1 stop bit */
    LinTwoStopBit   = 1,    /*!< 2 stop bits */
    LinThreeStopBit = 2,    /*!< 3 stop bits */
    LinFourStopBit  = 3     /*!< 4 stop bits */
} en_lin_stopbit_t;


/**
 *****************************************************************************
 ** \brief Checksum type selection.
 **
 *****************************************************************************/
typedef enum en_lin_checksum_type
{
    LinChecksumTypeNormal = 0,      /*!< Normal (classic) checksum */
    LinChecksumTypeExtended = 1     /*!< Extended (enhanced) checksum */
}en_lin_checksum_type_t;


/**
 *****************************************************************************
 ** \brief LIN configuration
 **        This settings are per LIN instance.
 *****************************************************************************/
typedef struct stc_lin_config
{
    /** If TRUE, corresponding channel = master mode, If FALSE, slave mode. */
    boolean_t                       bMasterMode;
    /** Break field length. See #en_lin_break_field_length_t */
    en_lin_break_field_length_t     enBreakFieldLength;
    /** Break delimiter length. See #en_lin_break_delimiter_length_t */
    en_lin_break_delimiter_length_t enBreakDelimiterLength;
    /** Stop bit length. See #en_lin_stopbit_t. */
    en_lin_stopbit_t                enStopBit;
    /** Data rate (bps) */
    uint32_t                        u32DataRate;
    /** Upper limit auto baud rate adjustment. (Effective only slave mode)
     ** This is the upper limit on the values that can be set in the baud rate
     ** generator register for auto baud rate adjustment.
     ** Does not data rate (bps)
     */
    uint16_t                        u16BgrUpperLimit;
    /** Lower limit auto baud rate adjustment. (Effective only slave mode)
     ** This is the lower limit on the values that can be set in the baud rate
     ** generator register for auto baud rate adjustment.
     ** Does not data rate (bps)
     */
    uint16_t                        u16BgrLowerLimit;
    /** Callback function, if status interrupt or error interrupt occurs.
     ** In this sample, can't be set to NULL.
     **/
    lin_status_cb_func_ptr_t        pfnStatusCb;
}stc_lin_config_t;


/*****************************************************************************/
/* Global variable declarations ('extern', definition in C source)           */
/*****************************************************************************/


/*****************************************************************************/
/* Global function prototypes ('extern', definition in C source)             */
/*****************************************************************************/
extern en_result_t Mfs_Lin_Init(pstc_lin_type_t pstcLin,
                            const stc_lin_config_t *pstcConfig);
extern en_result_t Mfs_Lin_SetAutoHeader(pstc_lin_type_t pstcLin,
                                     uint8_t u8Id,
                                     uint8_t u8DataLength,
                                     en_lin_checksum_type_t enChecksumType);
extern en_result_t Mfs_Lin_WriteData(pstc_lin_type_t pstcLin,
                                 const uint8_t *au8Data,
                                 uint8_t u8DataLength,
                                 en_lin_checksum_type_t enChecksumType);
extern en_result_t Mfs_Lin_ReadData(pstc_lin_type_t pstcLin,
                                uint8_t  *u8Data,
                                uint8_t  *u8Length);
extern en_result_t Mfs_Lin_GetReceivedId(pstc_lin_type_t pstcLin,
                                      uint8_t *u8Id,
                                      uint8_t *u8Parity);
extern en_result_t Mfs_Lin_EnableRx(pstc_lin_type_t pstcLin,
                                uint8_t  u8DataLength,
                                en_lin_checksum_type_t enChecksumType);
extern en_result_t Mfs_Lin_DisableRx(pstc_lin_type_t pstcLin);
extern en_result_t Mfs_Lin_EnableTx(pstc_lin_type_t pstcLin);
extern en_result_t Mfs_Lin_DisableTx(pstc_lin_type_t pstcLin);
extern en_result_t Mfs_Lin_GetReloadValue(uint32_t u32DataRate,
                                      uint32_t *u32ReloadValue);
extern en_result_t Mfs_Lin_GetBaudrateAdjustmentFlag(pstc_lin_type_t pstcLin,
                                                 boolean_t *bFlag);

/** @} */

#ifdef __cplusplus
}
#endif

#endif /* __MFS_LIN_H__ */
/*****************************************************************************/
/* EOF (not truncated)                                                       */
/*****************************************************************************/