/*
 * Copyright 2018 NXP
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * o Redistributions of source code must retain the above copyright notice, this list
 *   of conditions and the following disclaimer.
 *
 * o Redistributions in binary form must reproduce the above copyright notice, this
 *   list of conditions and the following disclaimer in the documentation and/or
 *   other materials provided with the distribution.
 *
 * o Neither the name of the copyright holder nor the names of its
 *   contributors may be used to endorse or promote products derived from this
 *   software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/*****************************************************************************
*
* \file nxp_sja1124_lin.h
*
* \author NXP
*
* \brief Functions for the LIN driver
*
*****************************************************************************/

#ifndef NXP_SJA1124_LIN_H
#define NXP_SJA1124_LIN_H

/*****************************************************************************
* INCLUDES
*****************************************************************************/

#include <SJA1124_Drv/nxp_sja1124.h>


/*****************************************************************************
* DEFINES
*****************************************************************************/

/* Internal limitation for number of channels supported by the driver. */
#define LIN_HW_MAX_MODULES 16u

/*****************************************************************************
* TYPE DEFINITIONS
*****************************************************************************/

/*
* \brief Break length.
* \details LIN master break length.
*/
typedef enum
{
  LIN_10BIT_BREAK = 0u,  /* 10 bit break length. */
  LIN_11BIT_BREAK = 1u,  /* 11 bit break length. */
  LIN_12BIT_BREAK = 2u,  /* 12 bit break length. */
  LIN_13BIT_BREAK = 3u,  /* 13 bit break length. */
  LIN_14BIT_BREAK = 4u,  /* 14 bit break length. */
  LIN_15BIT_BREAK = 5u,  /* 15 bit break length. */
  LIN_16BIT_BREAK = 6u,  /* 16 bit break length. */
  LIN_17BIT_BREAK = 7u,  /* 17 bit break length. */
  LIN_18BIT_BREAK = 8u,  /* 18 bit break length. */
  LIN_19BIT_BREAK = 9u,  /* 19 bit break length. */
  LIN_20BIT_BREAK = 10u, /* 20 bit break length. */
  LIN_21BIT_BREAK = 11u, /* 21 bit break length. */
  LIN_22BIT_BREAK = 12u, /* 22 bit break length. */
  LIN_23BIT_BREAK = 13u, /* 23 bit break length. */
  LIN_36BIT_BREAK = 14u, /* 36 bit break length. */
  LIN_50BIT_BREAK = 15u  /* 50 bit break length. */
} Lin_MasterBreakLengthType;

/*
* \brief Checksum models for the LIN Frame.
* \details This type is used to specify the Checksum model to be used for the LIN Frame.
*/
typedef enum
{
  LIN_ENHANCED_CS = 0u, /* Enhanced checksum model. */
  LIN_CLASSIC_CS = 1u   /* Classic checksum model. */
} Lin_FrameCsModelType;

/*
* \brief Frame response types.
* \details This type is used to specify whether the frame processor is required to transmit the response part of the LIN frame.
*/
typedef enum
{
  LIN_SLAVE_RESPONSE = 0u,  /* Response is generated from a remote slave node. */
  LIN_MASTER_RESPONSE = 1u  /* Response is generated from this (master) node. */
} Lin_FrameResponseType;

/*
* \brief LIN Frame and Channel states operation.
* \details LIN operation states for a LIN channel or frame, as returned by the API service Lin_GetStatus().
*/
typedef enum
{
  LIN_NOT_OK = 0u,          /* Development or production error occurred. */
  LIN_TX_OK = 1u,           /* Successful transmission. */
  LIN_TX_BUSY = 2u,         /* Ongoing transmission (Header or Response). */
  LIN_TX_HEADER_ERROR = 3u, /* Erroneous header transmission such as:
                               - Mismatch between sent and read back data,
                               - Identifier parity error,
                               - Physical bus error. */
  LIN_TX_ERROR = 4u,        /* Erroneous transmission such as:
                               - Mismatch between sent and read back data,
                               - Physical bus error. */
  LIN_RX_OK = 5u,           /* Reception of correct response. */
  LIN_RX_BUSY = 6u,         /* Ongoing reception (at least one response byte has been received,
                               but the checksum byte has not been received). */
  LIN_RX_ERROR = 7u,        /* Erroneous reception such as:
                               - Framing error,
                               - Overrun error,
                               - Checksum error,
                               - Short response. */
  LIN_RX_NO_RESPONSE = 8u,  /* No response byte has been received so far. */
  LIN_OPERATIONAL = 9u,     /* Normal operation, the related LIN channel is ready to transmit next header,
                               no data from previous frame available (e.g. after initialization). */
  LIN_CH_SLEEP = 10u        /* Sleep mode operation; in this mode wake-up detection from slave nodes is enabled. */
} Lin_StatusType;

/*
* \brief LIN channel configuration structure.
* \details This structure specifies the parameters of the LIN transmission for the channel.
*/
typedef struct
{
  /* LCFG1 register. */
  bool sleepMode;                              /* Enable sleep mode. */
  bool checksumCalcDisable;                    /* Checksum calculation disable. */
  Lin_MasterBreakLengthType masterBreakLength; /* LIN master break length. */
  /* LCFG2 register. */
  bool twoBitDelimiter;                        /* Delimiter length in break field. */
  bool idleOnBitError;                         /* Idle on bit error. */
  /* LITC register. */
  bool idleOnTimeout;                          /* Idle on timeout. */
  /* LGC register. */
  bool stopBits;                               /* 1 or 2 stop bits configuration. */
  /* LRTC register. */
  uint8_t responseTimeout;                     /* Response timeout value. */
  /* LFR register. */
  uint8_t fracBaudrate;                        /* Fractional baudrate. */
  /* LBRM and LBRL registers. */
  uint16_t intBaudrate;                        /* Integer baudrate. */
  /* LIE register. */
  uint8_t lie;                                 /* LIN interrupt enable register. */
} Lin_ChannelConfigType;

/*
* \brief LIN driver configuration type structure.
* \details This is the type of the pointer to the external data LIN Channels. A pointer of such a structure
           is provided to the LIN driver initialization routine for configuration of the LIN hardware channel.
*/
typedef struct
{
  uint8_t maxHWChannels; /* Gives the number of the maximum configured hardware channels in this configuration. */
  Lin_ChannelConfigType linChannel[4 * SJA1124_NUM_OF_DEVICES]; /* Pointer to structure containing the overall
                                                                   initialization data for all the LIN Channels.
                                                                   Config->LinChannel[0]  = device 1, channel 1,
                                                                   Config->LinChannel[1]  = device 1, channel 2,
                                                                   Config->LinChannel[4]  = device 2, channel 1,
                                                                   Config->LinChannel[5]  = device 2, channel 2,
                                                                   Config->LinChannel[15] = device 4, channel 4 etc. */
} Lin_ConfigType;

/*
* \brief Structure with frame details to send.
* \details This structure is used to provide PID, checksum model, data length and data pointer to the LIN driver.
*/
typedef struct
{
  /* LBI register. */
  uint8_t id;                /* LIN frame identifier. */
  /* LBC register. */
  uint8_t dfl;               /* Data field length (number of bytes - 1). */
  Lin_FrameResponseType dir; /* Response type (master or slave response). */
  Lin_FrameCsModelType ccs;  /* Checksum model type (classic or enhanced checksum calculation). */
  /* LCF register. */
  uint8_t cf;                /* Checksum to be transmitted in case checksum calculation is disabled. */
  /* LBDx registers. */
  uint8_t data[8];           /* Pointer to data to send. */
} Lin_PduType;

/*
* \brief Structure with channel status and received data.
* \details This structure contains received channel status and channel response.
*/
typedef struct
{
  /* LSTATE register. */
  bool rxbsy;                /* Receiver busy. */
  uint8_t lins;              /* LIN state machine status. */
  /* LES register. */
  uint8_t les;               /* LIN error status. */
  /* LS register. */
  uint8_t ls;                /* LIN status. */
  /* LCF register. */
  uint8_t cf;                /* Checksum received. */
  /* LBDx registers. */
  uint8_t data[8];           /* Pointer to received data. */
} Lin_SduType;

/*****************************************************************************
* FUNCTIONS
*****************************************************************************/

/*
* \brief The function Init initializes the LIN channels.
*
* \param[in] uint8_t device         - Device number (0..3 in case of 4 devices).
* \param[in] Lin_ConfigType* config - Pointer to LIN driver configuration set.
* \return Std_ReturnType            - E_OK: Send command has been accepted.
*                                     E_NOT_OK: Send command has not been accepted.
*/
Std_ReturnType Lin_Init(uint8_t device, const Lin_ConfigType* config);

/*
* \brief The function SendFrame sends the header part (Break Field,
*        Synch Byte Field and PID Field) and, depending on the direction
*        of the frame response, a complete LIN response part of a LIN
*        frame on the addressed LIN channel.
*
* \param[in] uint8_t channel     - LIN channel to be addressed (0..15 in case of 16 channels).
* \param[in] Lin_PduType* pduPtr - Pointer to PDU containing the PID, checksum model,
*                                  response type, Dl and SDU data pointer.
* \param[in] bool sendFrame      - true: Send the frame when calling this function.
*                                - false: Prepare necessary data, but don't send the frame
*                                         (might be used for synchronized frame sending).
* \return Std_ReturnType         - E_OK: Send command has been accepted.
*                                  E_NOT_OK: Send command has not been accepted.
*/
Std_ReturnType Lin_SendFrame(uint8_t channel, Lin_PduType* pduPtr, bool sendFrame);

/*
* \brief The function GoToSleep sends a go-to-sleep command on the addressed LIN channel
*        and puts corresponding master channel to sleep.
*
* \param[in] uint8_t channel - LIN channel to be addressed (0..15 in case of 16 channels).
* \return Std_ReturnType     - E_OK: Sleep command has been accepted.
*                              E_NOT_OK: Sleep command has not been accepted.
*/
Std_ReturnType Lin_GoToSleep(uint8_t channel);

/*
* \brief The function Wakeup wakes up corresponding master channel
*        and sends a wake-up command on the addressed LIN channel.
*
* \param[in] uint8_t channel - LIN channel to be addressed (0..15 in case of 16 channels).
* \return Std_ReturnType     - E_OK: Wake-up request has been accepted.
*                              E_NOT_OK: Wake-up request has not been accepted.
*/
Std_ReturnType Lin_Wakeup(uint8_t channel);

/*
* \brief The function GetStatus shall return the current transmission,
*        reception or operation status of the LIN driver. Status bits
*        are cleared afterwards if any are set. If slave response is
*        expected, the function also returns the response and checksum.
*
* \param[in] uint8_t channel      - LIN channel to be checked (0..15 in case of 16 channels).
* \param[in] Lin_PduType* pduPtr  - Pointer to a buffer or memory where the current PDU is stored.
* \param[out] Lin_SduType* sduPtr - Pointer to a buffer or memory where the current SDU is stored.
* \return Lin_StatusType          - LIN status response:
*                                     - LIN_NOT_OK: Development or production error occurred.
*                                     - LIN_CH_OPERATIONAL: Normal state operation, sub-states are:
*                                         - LIN_TX_OK: Successful transmission
*                                         - LIN_TX_BUSY: Ongoing transmission (Header or Response).
*                                         - LIN_TX_HEADER_ERROR: Erroneous header transmission such as:
*                                             - Mismatch between sent and read back data.
*                                             - Identifier parity error or Physical bus error.
*                                         - LIN_TX_ERROR: Erroneous response transmission such as:
*                                             - Mismatch between sent and read back data.
*                                             - Physical bus error
*                                         - LIN_RX_OK: Reception of correct response.
*                                         - LIN_RX_BUSY: Ongoing reception: at least one response byte
*                                           has been received, but the checksum byte has not been received.
*                                         - LIN_RX_ERROR: Erroneous response reception such as:
*                                             - Framing error,
*                                             - Overrun error,
*                                             - Checksum error or Short response.
*                                         - LIN_RX_NO_RESPONSE: No response byte has been received so far.
*                                         - LIN_OPERATIONAL: Normal operation; the related LIN channel
*                                           is just initialized or waked up from the LIN_CH_SLEEP
*                                           and no data has been sent.
*                                     - LIN_CH_SLEEP: Sleep state operation; in this state wake-up
*                                       detection from slave nodes is enabled.
*/
Lin_StatusType Lin_GetStatus(uint8_t channel, Lin_PduType* pduPtr, Lin_SduType* sduPtr);

/*
* \brief The function GetStatusFast shall return the current transmission,
*        reception or operation status of the LIN driver. Status bits
*        are cleared during the same transmission. If slave response is
*        expected, the function also returns the response and checksum.
*
* \param[in] uint8_t channel      - LIN channel to be checked (0..15 in case of 16 channels).
* \param[in] Lin_PduType* pduPtr  - Pointer to a buffer or memory where the current PDU is stored.
* \param[out] Lin_SduType* sduPtr - Pointer to a buffer or memory where the current SDU is stored.
* \return Lin_StatusType          - LIN status response:
*                                     - LIN_NOT_OK: Development or production error occurred.
*                                     - LIN_CH_OPERATIONAL: Normal state operation, sub-states are:
*                                         - LIN_TX_OK: Successful transmission
*                                         - LIN_TX_BUSY: Ongoing transmission (Header or Response).
*                                         - LIN_TX_HEADER_ERROR: Erroneous header transmission such as:
*                                             - Mismatch between sent and read back data.
*                                             - Identifier parity error or Physical bus error.
*                                         - LIN_TX_ERROR: Erroneous response transmission such as:
*                                             - Mismatch between sent and read back data.
*                                             - Physical bus error
*                                         - LIN_RX_OK: Reception of correct response.
*                                         - LIN_RX_BUSY: Ongoing reception: at least one response byte
*                                           has been received, but the checksum byte has not been received.
*                                         - LIN_RX_ERROR: Erroneous response reception such as:
*                                             - Framing error,
*                                             - Overrun error,
*                                             - Checksum error or Short response.
*                                         - LIN_RX_NO_RESPONSE: No response byte has been received so far.
*                                         - LIN_OPERATIONAL: Normal operation; the related LIN channel
*                                           is just initialized or waked up from the LIN_CH_SLEEP
*                                           and no data has been sent.
*                                     - LIN_CH_SLEEP: Sleep state operation; in this state wake-up
*                                       detection from slave nodes is enabled.
*/
Lin_StatusType Lin_GetStatusFast(uint8_t channel, Lin_PduType* pduPtr, Lin_SduType* sduPtr);

/*
* \brief The function GetStatusPoll shall return the current transmission,
*        reception or operation status of the LIN driver. Status bits
*        are cleared during the same transmission.
*
* \param[in] uint8_t channel - LIN channel to be checked (0..15 in case of 16 channels).
* \return Lin_StatusType     - LIN status response:
*                                - LIN_NOT_OK: Development or production error occurred.
*                                - LIN_CH_OPERATIONAL: Normal state operation, sub-states are:
*                                    - LIN_TX_OK: Successful transmission
*                                    - LIN_TX_BUSY: Ongoing transmission (Header or Response).
*                                    - LIN_TX_HEADER_ERROR: Erroneous header transmission such as:
*                                        - Mismatch between sent and read back data.
*                                        - Identifier parity error or Physical bus error.
*                                    - LIN_TX_ERROR: Erroneous response transmission such as:
*                                        - Mismatch between sent and read back data.
*                                        - Physical bus error
*                                    - LIN_RX_OK: Reception of correct response.
*                                    - LIN_RX_BUSY: Ongoing reception: at least one response byte
*                                      has been received, but the checksum byte has not been received.
*                                    - LIN_RX_ERROR: Erroneous response reception such as:
*                                        - Framing error,
*                                        - Overrun error,
*                                        - Checksum error or Short response.
*                                    - LIN_RX_NO_RESPONSE: No response byte has been received so far.
*                                    - LIN_OPERATIONAL: Normal operation; the related LIN channel
*                                      is just initialized or waked up from the LIN_CH_SLEEP
*                                      and no data has been sent.
*                                - LIN_CH_SLEEP: Sleep state operation; in this state wake-up
*                                  detection from slave nodes is enabled.
*/
Lin_StatusType Lin_GetStatusPoll(uint8_t channel);

#endif  /* NXP_SJA1124_LIN_H */
