/*
 * StmSupport.h
 *
 * STM Library support header file. This file is intended for internal use only. 
 *
 * Copyright (C) 2009,2010 Texas Instruments Incorporated - http://www.ti.com/ 
 * 
 * 
 *  Redistribution and use in source and binary forms, with or without 
 *  modification, are permitted provided that the following conditions 
 *  are met:
 *
 *    Redistributions of source code must retain the above copyright 
 *    notice, this list of conditions and the following disclaimer.
 *
 *    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.
 *
 *    Neither the name of Texas Instruments Incorporated 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 
 *  OWNER 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.
 *
*/
#ifndef __STMSUPPORT_H
#define __STMSUPPORT_H

#define STM_WORD_SIZE			(4)
#define OST_VERSION				(1 << 24)						//Restrictions: value must be between 1 and 15
#define OST_ENTITY_ID			(1 << 16)
#define OST_PROTOCOL_PRINTF		(0x80 << 8)						//STMXport_printf (STM messages pass %s pointer)
#define OST_PROTOCOL_BYTESTREAM	(0x81 << 8)	                    //STMXport_putMsg
#define OST_PROTOCOL_MSGSTREAM	(0x82 << 8)	                    //STMXport_putBuf
#define OST_PROTOCOL_INTERNALMSG (0x83 << 8)                    //STMXport_IntMsg (Internal Message)
#define OST_PROTOCOL_PRINTF_UNOPTIMIZED (0x84 << 8)             //STMXport_printf (STM messages pass %s byte stream)
#define OST_SHORT_HEADER_LENGTH_LIMIT	(255)

#ifdef C55XP_STM
//C55p is big endiam
	#define L0			(3)
	#define L1			(2)
	#define L2			(1)
	#define L3			(0)
#else
//ARM assumption is little
	#define L0			(0)
	#define L1			(1)
	#define L2			(2)
	#define L3			(3)
#endif

#define MAX_DMA_CHANNEL (31)
#define MAX_DMA_IRQ     (3)
#define STM_MAX_CHANNEL (240)
#define OST_SMALL_MSG   (255)

typedef enum
{
	eByteAlign = 1,
	eShortAlign = 2,
	eShortAndByteAlign = 3,
	eWordAlign = 4
}eAddrAlignment;

// DMA
#define DMA_OCPCntl				(DMA_BaseAddr + 0x2C )
#define DMA_FIFO            	(DMA_BaseAddr + 0x78 )
#define DMA_IrqOffset           (0x4)
#define DMA_IrqStatus(irqID)	((DMA_BaseAddr  + (irqID * DMA_IrqOffset)) + 0x8)
#define DMA_IrqEnable(irqID)    ((DMA_BaseAddr  + (irqID * DMA_IrqOffset)) + 0x18)			
#define DMA_ChOffset    		(0x60)
#define DMA_ChCntl(ch) 			((DMA_BaseAddr + (ch * DMA_ChOffset)) + 0x80 )
#define DMA_ChSrcDstPrms(ch)	((DMA_BaseAddr + (ch * DMA_ChOffset)) + 0x90 )
#define DMA_ChElem(ch)			((DMA_BaseAddr + (ch * DMA_ChOffset)) + 0x94 )
#define DMA_ChFram(ch)			((DMA_BaseAddr + (ch * DMA_ChOffset)) + 0x98 )
#define DMA_ChSrcAdd(ch)		((DMA_BaseAddr + (ch * DMA_ChOffset)) + 0x9C )
#define DMA_ChDstAdd(ch)		((DMA_BaseAddr + (ch * DMA_ChOffset)) + 0xA0 )
#define DMA_ChStatus(ch)		((DMA_BaseAddr + (ch * DMA_ChOffset)) + 0x8C )
#define DMA_ChLnkCntl(ch)		((DMA_BaseAddr + (ch * DMA_ChOffset)) + 0x84 )
#define DMA_ChIntCntl(ch)		((DMA_BaseAddr + (ch * DMA_ChOffset)) + 0x88 )

//DMA Status register bits of interest
#define DMA_ERROR_MASK 			(0x2F00)
#define DMA_FRAME_COMPLETE		(0x1<<3)
#define DMA_SYSTEM_ERROR		(0x1<<13)
#define DMA_MISSALIGND_ERROR 	(0x1<<11)
#define DMA_SUPERVISOR_ERROR	(0x1<<10)
#define DMA_SECURE_ERROR		(0x1<<9)
#define DMA_TRASACTION_ERROR	(0x1<<8)

//DMA Control bits
#define DMA_CONTROL_MASK 		(0x80)
#define DMA_ENABLE 				(0x1<<7)

#define VALIDATE_NULL_VALUE(value) if (NULL == value) return eSTM_ERROR_PARM

#define RETURN_CALLBACK(pCallBack, retValue) 		if ( NULL != pCallBack ) pCallBack(__FUNCTION__, retValue); return retValue
										

typedef enum
{
	eRegular = 1,
	eTiming = 2
}eAddressType;

typedef struct _STMMsgObj 
{
    void *              pMsg;                   // Pointer to message
    uint32_t            elementCnt;             // number of elements
    eSTMElementSize     elementSize;            // element size
    int32_t             chNum;                  // STM channel id
    bool                DMA_SingleAccessMode;   // Use Burst or Single Access modes
    STMXport_callback   pCallBack;              // Callback function
    bool                DMA_posted;             // message posted to DMA
    struct _STMMsgObj * pNextMsg;               // next message in the link list
    struct _STMMsgObj * pPrevMsg;               // prev message in the link list
}STMMsgObj;

// Internal Functions
inline uint32_t Compose_Address(uint32_t ulBaseAddr, int32_t chNum, uint32_t size, eAddressType addrType);
void Compose_OST_MSG(const char *pInputBuf, int32_t iInputBufSize, const char *pOSTHeader, int32_t iHeaderSizeInByte, char *pReturnBuf);
void Build_OST_Header(uint32_t protocolID, uint32_t numberOfBytes, uint32_t *pReturnBuf, int32_t *pBufSizeInBytes);
inline uint32_t Build_CompactOST_Header(uint32_t protocolID, uint32_t numberOfBytes );
inline void Build_ExtendedOST_Header(uint32_t protocolID, uint32_t numberOfBytes, uint32_t *pReturnBuf);
eAddrAlignment AddressAlignmentChecker(uint32_t address);

//External Functions
extern void * cTools_memAlloc(size_t sizeInBytes);
extern void  cTools_memFree(void *);
extern void * cTools_memMap(uint32_t phyAddress, size_t mapSizeInBytes);
extern void  cTools_memUnMap(void * vAddress, size_t mapSizeInBytes);

//Exported Functions meant to be used by other Libraries
/*! \par STMExport_IntMsg         
    
    Internal Message: This method is meant to be used by other STM Libraries to provide meta data or
    logging messages. It will transport over STM all the elements required to form a complete message
    sample. This function does not require any knowledge by the decoder as to which library was the source
    of the data.  
   
    \param[in] pSTMHandle  A pointer to an STM Handle returned by STMXport_open().
    \param[in] chNum       A STM Channel number in the range of 0 to 254 (255 reserved).
                           The most common usage is to identify messages coming from
                           different OS tasks or processes. It's expected the application
                           will manage it's channel usage.
    \param[in] pModuleName Pointer to a global static Module Name string  
    \param[in] pDomainName Pointer to a global static Domain Name string
    \param[in] pDataClass  Pointer to a global static Data Class string
    \param[in] pDataType   Pointer to a global static Data Type string
    \param[in] pDataMsg    Pointer to a global static Data Message string
    \param[in] pData       Pointer to a unsigned int Data value

    \return eSTM_STATUS    Function's exit status. 

    \par Details:
    \details   
    
    This function is utilized to transport the pointer to a static strings and a 32-bit data value.
    All elements are transported using 32-bit STM transfers. 
	
*/
eSTM_STATUS STMExport_IntMsg (STMHandle * pSTMHandle, int32_t chNum, 
                              const char * pModuleName, const char * pDomainName,
                              const char * pDataClass, const char * pDataType,
                              const char * pDataMsg, uint32_t *  pData);

eSTM_STATUS STMExport_putMeta(STMHandle* pSTMHandle, const char* pMsgString, int32_t iMsgByteCount);

#pragma CODE_SECTION(STMExport_IntMsg,      ".text:STMLibraryFast")
#pragma CODE_SECTION(STMExport_putMeta,     ".text:STMLibraryFast")

// Msg handling routines
eSTM_STATUS STM_putBufCPU(STMHandle * pHandle, int32_t iChNum, void * pHdrBuf, int32_t iHdrWrdCnt, void * pMsgBuf, uint32_t iElementCnt, eSTMElementSize iElementSize);
eSTM_STATUS STM_putMsgCPU(STMHandle * pHandle, int32_t iChNum, void * pHdrBuf, int32_t iHdrWrdCnt, void * pMsgBuf, uint32_t iMsgByteCnt);
eSTM_STATUS STM_putDMA(STMHandle* pHandle, int32_t iChNum, void* pMsgBuf, uint32_t iElementCnt, eSTMElementSize iElementSize, bool DMASingleAccessMode, STMXport_callback pCallBack);
eSTM_STATUS STM_printfV(STMHandle* pSTMHandle, int32_t chNum, const char* pMsgString, va_list arg_addr);

//DMA Helper routines
eSTM_STATUS DMA_checkStatus(STMHandle* pHandle);
void DMA_serviceNextMsg(STMHandle* pHandle);
void DMA_postMsg(STMHandle* pHandle, STMMsgObj * msgObj);

#pragma CODE_SECTION(Compose_Address, 			".text:STMLibraryFast")
#pragma CODE_SECTION(Compose_OST_MSG, 			".text:STMLibraryFast")
#pragma CODE_SECTION(Build_OST_Header, 			".text:STMLibraryFast")
#pragma CODE_SECTION(AddressAlignmentChecker, 	".text:STMLibraryFast")
#pragma CODE_SECTION(STM_putBufCPU, 			".text:STMLibraryFast")
#pragma CODE_SECTION(STM_putMsgCPU, 			".text:STMLibraryFast")
#pragma CODE_SECTION(STM_putDMA, 				".text:STMLibraryFast")
#pragma CODE_SECTION(DMA_checkStatus, 			".text:STMLibraryFast")
#pragma CODE_SECTION(DMA_serviceNextMsg, 		".text:STMLibraryFast")
#pragma CODE_SECTION(DMA_postMsg, 				".text:STMLibraryFast")



#endif /* __STMSUPPORT_H */
