#ifndef __SEP_DRIVER_H__
#define __SEP_DRIVER_H__


/*
   *  Object %name    : SEPDriver.h
   *  State           :  %state%
   *  Creation date   :  Wed Nov 17 17:39:24 2004
   *  Last modified   :  %modify_time%
   */
  /** @file
   *  \brief  SEP Driver h file (API and structures )
   *
   *  \version 
   *  \author yevgenys
   *  \remarks Copyright (C) 2004 by Discretix Technologies Ltd.
   *           All Rights reserved
   */


/*------------------------------
    DEFINES
--------------------------------*/

/* the paramater is of type byte array - no need for endiannes */
#define SEP_DRIVER_PARAM_TYPE_BYTE_ARRAY    0x0

/* the paramter is of type word array */
#define SEP_DRIVER_PARAM_TYPE_WORD_ARRAY    0x1

#define SEP_DRIVER_NVS_EVENT                (0x2UL)

#define SEP_DRIVER_SHARED_MEMORY_BYTES_IN_WORD  (0x4UL)
#define SEP_DRIVER_SHARED_MEMORY_NUM_OF_K       (0x6UL)
#define SEP_DRIVER_SHARED_MEMORY_WORDS_IN_K     (0x100UL)
#define SEP_DRIVER_SHARED_MEMORY_SIZE_IN_WORDS  (SEP_DRIVER_SHARED_MEMORY_NUM_OF_K * SEP_DRIVER_SHARED_MEMORY_WORDS_IN_K * SEP_DRIVER_SHARED_MEMORY_BYTES_IN_WORD)
#define SEP_DRIVER_SHARED_MEMORY_SIZE_IN_BYTES  ((SEP_DRIVER_SHARED_MEMORY_SIZE_IN_WORDS) * sizeof(DxUint32_t))

/* define for no timeout - block until message received */
#define SEP_DRIVER_TIMEOUT_1_SECOND             (1000UL)
#define SEP_DRIVER_TIMEOUT_5_SECONDS            (5 * SEP_DRIVER_TIMEOUT_1_SECOND)
#define SEP_DRIVER_TIMEOUT_WAIT_FOR_INIFINITY   (0xFFFFFFFF)

/*-------------------------------
  STRUCTURES
---------------------------------*/

/* enum defines the direction of the buffer - input data or output data */
typedef enum
{
  SEP_DRIVER_InputBuffer = 0,
  SEP_DRIVER_OutputBuffer = 1,
  SEP_DRIVER_OutputBufferLast = 0x7fffffff,
}SEPDriver_BufferDirection_t;

/* structure defining one input buffer of flows: the pointer to buffer and buffer size */
typedef struct _SEP_FLOW_BufferData_t
{
  /* buffer pointer */
  DxUint8_t*   buffer_ptr;
  
  /* buffer size */
  DxUint32_t   bufferSize;
  
}SEP_FLOW_BufferData_t;

/*-------------------------
  enum for types of polling while waiting for response from SEP 
-----------------------------*/
typedef enum
{
  SEP_DRIVER_EVENT,
  SEP_DRIVER_POLLING,
  SEP_DRIVER_POLLING_WITH_CALLBACK,

  SEPDriver_PollingTypeLast= 0x7FFFFFFF,

}SEPDriver_PollingType_t;

/* type of function that should be called as response to the SEP callback */
typedef DxError_t (*SEP_CallbackFunc)(void);


/***********************************************************************
* @brief       this structure defines the element in the array of the contextes for flows
***********************************************************************/
/*This MACRO is used to calculate max length for parameters*/
#define SEPDriver_ALIGNED_TO_MAX_LENGTH(len)  ((len + 3) & 0xFFFFFFFC)
/*------------------------------------------------
    FUNCTIONS
--------------------------------------------------*/

/**
 * @brief       This define is used when calling the WaitFor response with polling
 * 
 * @param[in] sharedRamAddress - start address of the shared Ram
 * @return     DxError_t:  
 *                        
 */

#define SEPDriver_POLL_FOR_REPONSE() SEPDriver_WaitForResponse(SEP_DRIVER_POLLING , 0 , DX_NULL , SEP_DRIVER_TIMEOUT_WAIT_FOR_INIFINITY)

/**
 * @brief       This define is used when calling SEPDriver_PrepareSymDMATables to construc only one (input) table
 *
 * @param[in] DataIn_ptr - start address of the input data
 * @param[in] dataInSize - size of input data in bytes.
 * @param[out] firstInTable_ptr - pointer to physical address of the first input table
 * @param[out] firstTableNumEntries_ptr - pointer to the number of entries in the first input table ( the same for input and output)
 * @param[out] firstTableDataSize_ptr - pointer to the data in the first in table ( the same for input and output)
 *                        
 */
#define SEPDriver_PREPARE_INPUT_SYM_DMA_TABLE(DataIn_ptr , DataInSize , firstInTable_ptr ,firstTableNumEntries_ptr , firstTableDataSize_ptr) SEPDriver_PrepareSymDMATables((DxUint32_t)DataIn_ptr, \
                                                                                                                                                                                       0, \
                                                                                                                                                                                       DataInSize, \
                                                                                                                                                                                       0, \
                                                                                                                                                                                       firstInTable_ptr, \
                                                                                                                                                                                       DX_NULL, \
                                                                                                                                                                                       firstTableNumEntries_ptr, \
                                                                                                                                                                                       DX_NULL, \
                                                                                                                                                                                       firstTableDataSize_ptr)

/**
 * @brief       This function initializes the SEP Driver
 * 
 * @param[in] sharedRamAddress - start address of the shared Ram
 *
 */
void SEPDriver_Init(DxUint32_t sharedRamAddress);


/**
 * @brief       This function check that the resident and the cache are not being overwritten by the 
 *              internal configuration of the SEPDriver and FVOS
 *
 * 
 * @param[in] HostSharedAreaSize - the size of the shared area
 *
 */
DxError_t SEPDriver_CheckInitParams(DxUint32_t    hostSharedAreaSize);


/**
 * @brief       This function start the message in the SRAM. It inserts the token and the total length of the message,
 *              and returns the offset into message from where to start writing the next paramater
 *
 * @param[out] messageOffset_ptr - offset of the next paramater to be written into the message
 *
 */
void SEPDriver_StartMessage(DxUint32_t*  messageOffset_ptr);
                                       

/**
 * @brief       This function ends the message in the SRAM. It inserts CRS and then raises the interrupt to SEP
 *
 * @param[in] messageOffset - 
 *
 */
void SEPDriver_EndMessage(DxUint32_t   messageOffset);


/**
 * @brief       This function ends the reply message in the SRAM. It inserts CRS and then sets GPR2 to the value that SEP is polling on
 *              Reply message is the message sent from host to SEP as a result of SEP request (NVS)
 *
 * @param[in] messageOffset - 
 *
 */
void SEPDriver_EndReplyMessage(DxUint32_t   messageOffset);


/**
 * @brief       This function start the incoming message from SEP. It checks the start token , the length and the CRC
 *
 * @param[out] messageOffset_ptr - offset of the next paramater to be read from the message
 *
 * @return     DxError_t:  
 *                        
 */
DxError_t SEPDriver_StartIncomingMessage(DxUint32_t*  messageOffset_ptr);



                                     

/**
 * @brief       This function writes a a parameter into SHARED memory. Paramter can be either a word or an array of words or bytes
 *              If this is an array of bytes, then the bytesArrayFlag should be set, so that the parameter will be converted into little endian (if needed)
 *
 * @param[in] paramAddress - address pf the parameter to insert
 * @param[in] paramLengthInBytes - parameter length in bytes
 * @param[in] maxParamLengthInBytes - maximum number of bytes that this parameter should take in the message.Must be word alligned
 * @param[in/out] messageOffset_ptr - offset into message before and after insertion
 * @param[in] bytesArrayFlag - if this is byte array that should be converted
 *  
 * @return: Error - if the maxParamLengthInBytes is not word alligned                      
 */
DxError_t SEPDriver_WriteParamater(DxUint32_t   paramAddress,
                                   DxUint32_t   paramLengthInBytes,
                                   DxUint32_t   maxParamLengthInBytes,
                                   DxUint32_t*  messageOffset_ptr,
                                   DxUint32_t   bytesArrayFlag);
                                 
/**
 * @brief       This function reads a a parameter from SHARED memory. Paramter can be either a word or an array of words or bytes
 *              If this is an array of bytes, then the bytesArrayFlag should be set, so that the parameter will be converted into little endian (if needed)
 *
 * @param[in] paramAddress - address of the parameter to read
 * @param[in] paramLengthInBytes - parameter length in bytes
 * @param[in] maxParamLengthInBytes - maximum number of bytes that this parameter should take in the message.Must be word alligned
 * @param[in/out] messageOffset_ptr - offset into message before and after insertion
 * @param[in] bytesArrayFlag - if this is byte array that should be converted
 *
 * @return: Error - if the maxParamLengthInBytes is not word alligned  
 */
DxError_t SEPDriver_ReadParamater(DxUint32_t    paramAddress ,
                                  DxUint32_t    paramLengthInBytes,
                                  DxUint32_t    maxParamLengthInBytes,
                                  DxUint32_t*   messageOffset_ptr,
                                  DxUint32_t    bytesArrayFlag);


/**
 * @brief       This function locks access to the SEP driver and though it to the SEP
 *
 * @param[in] 
 *
 */
DxError_t SEPDriver_Lock(void);

/**
 * @brief       This function unlocks access to the SEP driver and though it to the SEP
 *
 * @param[in] 
 *
 * @return     DxError_t: 
 */
void SEPDriver_Unlock(void);

/**
 * @brief       This function waits for response from SEP(either by polling , or by event )
 *
 * @param[in] type - the type of polling - event, polling
 * @param[in] eventId - id of event in case type is EVENT, otherwise 0.
 * @param[in] callbackFunc_ptr - call back function in case the type is polling with callback
 * 
 * @return     DxError_t:  
 *
 */
DxError_t SEPDriver_WaitForResponse(SEPDriver_PollingType_t type , 
                                    DxUint32_t              eventId,
                                    SEP_CallbackFunc        callbackFunc_ptr,
                                    DxUint32_t              timeOut);


/**
 * @brief       This function builds the DMA tables for symmetric CRYS APIs
 *
 * @param[in] dataInAddr - start address of the input data
 * @param[in] dataOutAddr - start address of the input data. If it is 0, then no output tables will be generated
 * @param[in] dataInSize - size of input data in bytes.
 * @param[in] blockSize - virtual allocated address
 * @param[out] firstInTable_ptr - pointer to physical address of the first input table
 * @param[out] firstOutTable_ptr - pointer to physical address of the first output table
 * @param[out] firstInTableNumEntries_ptr - pointer to the number of entries in the first input table
 * @param[out] firstOutTableNumEntries_ptr - pointer to the number of entries in the first output table
 * @param[out] firstTableDataSize_ptr - pointer to the data in the first in table ( the same for input and output)
 * 
 * @return     DxError_t:  
 *
 */
DxError_t SEPDriver_PrepareSymDMATables(DxUint32_t    dataInAddr,
                                        DxUint32_t    dataOutAddr,
                                        DxUint32_t    dataInSize,
                                        DxUint32_t    blockSize,
                                        DxUint32_t*   firstInTable_ptr,
                                        DxUint32_t*   firstOutTable_ptr,
                                        DxUint32_t*   firstInTableNumEntries_ptr,
                                        DxUint32_t*   firstOutTableNumEntries_ptr,
                                        DxUint32_t*   firstTableDataSize_ptr);


/**
 * @brief       This function performs the needed clenup after the DMA action is finished.Depending on the enviroment
 *              it frees any dynamically allocted resources
 *
 * @return     DxError_t:  
 *
 */
DxError_t SEPDriver_FreeDMATables(void);

/**
 * @brief       This allocates a memory from the data pool according to the rquired length.
 *              It returns the virtual address and the physical address of the allocated memory
 *              The virtual address can be used later for reading or writing from the allocated memory
 *              the physical address is used for passing as argument to SEP
 *
 * @param[in] userDataInOut_ptr - user pointer to the data to be later written or read into
 * @param[in] sizeInBytes - size in bytes to allocated
 * @param[in] physAddr_ptr - physical allocated address.
 * @param[in] virtAddr_ptr - virtual allocated address
 * 
 * @return     DxError_t:  
 *
 */
 
/**
 * @brief       This function builds flow DMA table from the input buffer
 *
 * @param[in] flowType - static or dynamic
 * @param[in] bufferAddr - address of the input buffer (virtual)
 * @param[in] bufferLen - length of the input buffer
 * @param[in] inputOutputFlag - if the tables being built are for input or output
 * @param[out] firstLLITableAddr_ptr - physical address of the first DMA table
 * @param[out] numEntries_ptr - number of entries in the first DMA table
 * @param[out] tableDataSize_ptr - total data size in the first dma table 
 *
 * @return     DxError_t:  
 *
 */
DxError_t SEPDriver_PrepareFlowDMATables(DxUint32_t                   flowType,   
                                         SEP_FLOW_BufferData_t*       buffersArray_ptr,
                                         DxUint32_t                   buffersArrayLen,
                                         SEPDriver_BufferDirection_t  inputOutputFlag,
                                         DxUint32_t*                  firstLLITableAddr_ptr,
                                         DxUint32_t*                  numEntries_ptr,
                                         DxUint32_t*                  tableDataSize_ptr);
                                         
/**
 * @brief       This function sets the id for the tables which were created for the new flow, and had no id during creation 
 *
 * @param[in] flowId - flow id to set
 *
 * @return     DxError_t:  
 *
 */
void SEPDriver_SetFlowId(DxUint32_t flowId);


/**
 * @brief       This function frees all SEP tables resources
 *
 * @param[in] flowId - flow id to set
 *
 * @return     DxError_t:  
 *
 */
void SEPDriver_FreeFlowResources(DxUint32_t flowId);


/**
 * @brief       This function prepares the tables for additional buffers for the flow
 *
 * @param[in] flowId - id of flow to whom this message belongs
 * @param[in] inputOutputFlag - if the prepared table are input or output
 * @param[in] buffersArray_ptr - virtual buffers array
 * @param[in] buffersArraySize - virtual buffers array size
 * @param[out] lliTableAddr_ptr - address of the first table of the added buffers
 * @param[out] numEntriesInTable_ptr - number of entries in the first table
 * @param[out] tableDataSize_ptr - data size in the first table
 *
 * @return     DxError_t:  
 *
 */
DxError_t SEPDriver_AddFlowBuffers(DxUint32_t             flowId , 
                                   DxUint32_t             inputOutputFlag,
                                   SEP_FLOW_BufferData_t* buffersArray_ptr , 
                                   DxUint32_t             buffersArraySize,
                                   DxUint32_t*            lliTableAddr_ptr,
                                   DxUint32_t*            numEntriesInTable_ptr,
                                   DxUint32_t*            tableDataSize_ptr);


/**
 * @brief       This function construct the ADD BUFFERS TO FLOW message based on the message data and sends it to FVOs for storage
 *
 * @param[in] flowId - id of flow to whom this message belongs
 * @param[in] messageData_ptr - array of words that contains the data of message  - will be inserted as is into message
 * @param[in] messageSizeInWords - size of messageData_ptr in words
 *
 * @return     DxError_t:  
 *
 */
void SEPDriver_AddBufferMessage(DxUint32_t  flowId,
                                DxUint32_t* messageData_ptr,
                                DxUint32_t  messageSizeInWords);
 
 
DxError_t SEPDriver_AllocateDataPoolMemory(DxUint8_t*       userDataInOut_ptr,
                                           DxUint32_t       sizeInBytes, 
                                           DxUint32_t*      physAddr_ptr,
                                           DxUint32_t*      virtAddr_ptr);
                                           
/**
 * @brief       This functions writes data into the pre-allocated memory in the data pool. The address
 *              to write is defined by the virtAddr_ptr, and must be recieved previously from the SEPDriver_AllocateDataPoolMemory
 *              function
 *
 * @param[in] virtAddr_ptr - address in the data pool to write into
 * @param[in] dataIn_ptr - data to write.
 * @param[in] dataInSize - length in bytes of data to write
 * 
 * @return     DxError_t:  
 *
 */
DxError_t SEPDriver_WriteToDataPoolMemory(DxUint32_t  virtAddr_ptr, 
                                          DxUint8_t*  dataIn_ptr,
                                          DxUint32_t  dataInSize);
                                          
/**
 * @brief       This functions reads data from the pre-allocated memory in the data pool. The address
 *              to be read is defined by the virtAddr_ptr, and must be recieved previously from the SEPDriver_AllocateDataPoolMemory
 *              function
 *
 * @param[in] virtAddr_ptr - address in the data pool to read from
 * @param[in] dataIn_ptr - memory to read into.
 * @param[in] dataInSize - length in bytes of data to read
 * 
 * @return     DxError_t:  
 *
 */
DxError_t SEPDriver_ReadFromDataPoolMemory(DxUint32_t  virtAddr_ptr, 
                                           DxUint8_t*  dataOut_ptr,
                                           DxUint32_t  dataOutSize);

/**
 * @brief       This function returns the memory address of the static pool. This pool is allocated during init of the Host
 *              and currently will be used by SEP and NVS for SST purposes
 *
 * @param[out] physMemoryAddr_ptr - physical address of the static pool
 * @param[out] fvosMemoryAddr_ptr - FVOS (virtual kernel) address of the static pool
 * 
 * @return     DxError_t:  
 *
 */
DxError_t SEPDriver_GetStaticMemoryAddr(DxUint32_t* physMemoryAddr_ptr,
                                        DxUint32_t* fvosMemoryAddr_ptr);

/*
*   @brief This function set blocking mode of the access to SEP. If blocking  - then wait until semaphore is released,
*          if non-blocking - exit with appropriate error if the sempahore is currently taken
*          
*
*   @param[in] blockingMode - 1 - blocking mode, 0 - non-blocking mode. 
*
*   Returns:  Status of the operation.
*/
DxError_t SEPDriver_SetAPIBlockingMode(DxUint32_t blockingMode);

/*
*   @brief This function returns physical addres where the RT time value is stored
*
*   @param[out] timeAddress_ptr - address where the RT time value is stored
*
*   Returns:  Status of the operation.
*/
DxError_t SEPDriver_GetTime(DxUint32_t* timeAddress_ptr);

/**
 * @brief       This function calculates the check sum on the given data 
 *
 * @param[in] data- data to perfrom checksum on
 * @param[in] length - length of data
 *
 * @return  DxUint32_t  - Checksum 
 *                        
 */
DxUint32_t SEPDriver_CheckSumCalc(DxUint8_t *data, DxUint32_t length);


#endif
