/*
 * Copyright 2020-2023 Yuntu Microelectronics co.,ltd
 * All rights Resulterved.
 *
 * YUNTU Confidential. This software is owned or controlled by YUNTU and may
 * only be used strictly in accordance with the applicable license terms. By expResultsly
 * accepting such terms or by downloading, installing, activating and/or otherwise
 * using the software, you are agreeing that you have read, and that you agree to
 * comply with and are bound by, such license terms. If you do not agree to be
 * bound by the applicable license terms, then you may not retain, install,
 * activate or otherwise use the software. The production use license in
 * Section 2.3 is expResultsly granted for this software.
 */

#ifndef CAN_STACK_FIFO_H_
#define CAN_STACK_FIFO_H_

/* ============================================================================================== */
/*                                          INCLUDE FILES                                         */
/* ============================================================================================== */
#include "cantp.h"

typedef unsigned short cantp_fifo_id_type;

typedef unsigned short cantp_fifo_length_type;

typedef enum
{
    FIFO_EMPTY,										/**< fifo empty */
    FIFO_USING,										/**< fifo using */
    FIFO_FULL										/**< fifo full  */
} cantp_fifo_state_type;

typedef struct
{
    cantp_bool isTransmitting;
    cantp_u16 copiedLoc;
    pdu_info_type_t pduInfo;
} cantp_fifo_msg_info_type_t;

typedef struct
{
    cantp_fifo_id_type id;                          /**< Fifo id */
    cantp_fifo_length_type len;                     /**< Fifo total len */
    cantp_fifo_length_type readCnt;                 /**< read fifo counter */
    cantp_fifo_length_type writeCnt;                /**< write fifo counter */
    cantp_fifo_state_type fifoStatus;       	    /**< fifo status*/
    cantp_u8* beginAddr;	                        /**< start fifo addr */
    cantp_fifo_msg_info_type_t * lastMsgInfoPtr;    /**< Pointer point to the last sdu buffer */
} cantp_fifo_info_type_t;

/* ============================================================================================== */
/*                                            FUNCTIONS                                           */
/* ============================================================================================== */
/**
 * @brief Push a Sdu in fifo.
 *
 * @param[in] fifoId Fifo id.
 * @param[in] pduInfoPtr Pointer point to the sdu data struct.
 * @return cantp_fifo_res_type
 */
cantp_fifo_res_type CanTp_Fifo_PushSdu(cantp_fifo_id_type fifoId, const pdu_info_type_t* pduInfoPtr);

/**
 * @brief Pop a Sdu in fifo
 *
 * @param[in] fifoId Fifo id.
 * @return cantp_fifo_res_type
 */
cantp_fifo_res_type CanTp_Fifo_PopSdu(cantp_fifo_id_type fifoId);

/**
 * @brief return a Sdu msg in fifo.
 *
 * @param[in] fifoId Fifo id.
 * @param[out] pduInfoPtr Pointer point to the sdu data struct.
 * @return cantp_fifo_res_type
 */
cantp_fifo_res_type CanTp_Fifo_GetSdu(cantp_fifo_id_type fifoId, pdu_info_type_t* pduInfoPtr);

/**
 * @brief Start to receive a Sdu, after called several `CanTp_Fifo_PushPdu` called
 *        `CanTp_Fifo_FinishSdu` to complete a Sdu receive.
 *
 * @param[in] fifoId Fifo Id.
 * @param[in] pduInfoPtr Pointer point to the sdu data struct.
 * @return cantp_fifo_res_type
 */
cantp_fifo_res_type CanTp_Fifo_StartSdu(cantp_fifo_id_type fifoId, const pdu_info_type_t* pduInfoPtr);

/**
 * @brief Stop of receive a Sdu
 *
 * @param[in] fifoId Fifo id.
 * @param[in] sduRes Finish by error or ok.
 * @return cantp_fifo_res_type
 */
cantp_fifo_res_type CanTp_Fifo_FinishSdu(cantp_fifo_id_type fifoId, cantp_core_res_type sduRes);


/**
 * @brief Apply a fifo in memory.
 *
 * @param[in] fifoId Fifo id.
 * @param[in] fifoLen Fifo Len needed.
 * @return cantp_fifo_res_type
 */
cantp_fifo_res_type CanTp_Fifo_ApplyFifo(cantp_fifo_length_type fifoId, cantp_fifo_length_type fifoLen);

/**
 * @brief Copy a Pdu data to a location.
 *
 * @param[in] fifoId Fifo id.
 * @param[in] len Pdu data len.
 * @param[in] ptr Pointer point to pdu data buffer.
 * @return cantp_fifo_res_type
 */
cantp_fifo_res_type CanTp_Fifo_PopPduData(cantp_fifo_id_type fifoId, cantp_fifo_length_type len, cantp_u8* ptr);

/**
 * @brief Copy a pdu data to a fifo.
 *
 * @param[in] fifoId Fifo id.
 * @param[in] pduInfoPtr Pointer point to pdu data struct.
 * @return cantp_fifo_res_type
 */
cantp_fifo_res_type CanTp_Fifo_PushPduData(cantp_fifo_id_type fifoId, cantp_fifo_length_type len, cantp_u8* ptr);


/**
 * @brief Get the Can Write len object
 *
 * @param fifoId Fifo id.
 * @return cantp_fifo_length_type
 */
cantp_fifo_length_type CanTp_Fifo_GetCanWriteLen(cantp_fifo_id_type fifoId);

/**
 * @brief Return a fifo array.
 *
 * @return cantp_fifo_info_type_t**
 */
cantp_fifo_info_type_t** CanTp_Fifo_GetFifoArray();

/**
 * @brief Get the Fifo First Pdu pduInfoPtr object.
 *
 * @param[in] fifoId Fifo id.
 * @return cantp_fifo_msg_info_type_t*
 */
cantp_fifo_msg_info_type_t* CanTp_Fifo_GetMsgPtr(cantp_fifo_id_type fifoId);


/**
 * @brief Check if the fifo is not empty and ready to transmit data.
 *
 * @param[in] fifoId Fifo id.
 * @param[out] pendingLength data needed to be transmit.
 * @return cantp_bool
 */
cantp_bool CanTp_Fifo_IsWaitTx(cantp_fifo_id_type fifoId, cantp_u32* pendingLength);

/**
 * @brief This function will init cantp_fifo layer.
 *
 * @return cantp_return_type
 */
cantp_fifo_res_type CanTp_Fifo_Init();

/**
 * @brief uninit the fifo.
 *
 * @return cantp_fifo_res_type
 */
cantp_fifo_res_type ResetFifo();



#endif /*#ifndef CAN_STACK_FIFO_H_*/
