From 3c9433e21c91042d90622c37ae45fa55ed2e563a Mon Sep 17 00:00:00 2001 From: mattf Date: Fri, 20 Jul 2007 19:14:09 +0000 Subject: Merged revisions 2762 via svnmerge from https://origsvn.digium.com/svn/zaptel/branches/1.4 ................ r2762 | mattf | 2007-07-20 13:54:20 -0500 (Fri, 20 Jul 2007) | 9 lines Merged revisions 2761 via svnmerge from https://origsvn.digium.com/svn/zaptel/branches/1.2 ........ r2761 | mattf | 2007-07-20 11:19:47 -0500 (Fri, 20 Jul 2007) | 1 line New product support, new echo canceler and new boards ........ ................ git-svn-id: http://svn.digium.com/svn/zaptel/trunk@2763 5390a7c7-147a-4af0-8ec9-7488f05a26cb --- wctdm24xxp/GpakApi.c | 1609 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1609 insertions(+) create mode 100644 wctdm24xxp/GpakApi.c (limited to 'wctdm24xxp/GpakApi.c') diff --git a/wctdm24xxp/GpakApi.c b/wctdm24xxp/GpakApi.c new file mode 100644 index 0000000..2abb67a --- /dev/null +++ b/wctdm24xxp/GpakApi.c @@ -0,0 +1,1609 @@ +/* + * Copyright (c) 2005, Adaptive Digital Technologies, Inc. + * + * File Name: GpakApi.c + * + * Description: + * This file contains user API functions to communicate with DSPs executing + * G.PAK software. The file is integrated into the host processor connected + * to C55X G.PAK DSPs via a Host Port Interface. + * + * Version: 1.0 + * + * Revision History: + * 06/15/05 - Initial release. + * 11/15/2006 - 24 TDM-TDM Channels EC release + */ + +#include "GpakHpi.h" +#include "GpakCust.h" +#include "GpakApi.h" +#include "gpakenum.h" + +/* DSP to Host interface block offsets. */ +#define REPLY_MSG_PNTR_OFFSET 0 /* I/F blk offset to Reply Msg Pointer */ +#define CMD_MSG_PNTR_OFFSET 2 /* I/F blk offset to Command Msg Pointer */ +#define EVENT_MSG_PNTR_OFFSET 4 /* I/F blk offset to Event Msg Pointer */ +#define PKT_BUFR_MEM_OFFSET 6 /* I/F blk offset to Packet Buffer memory */ +#define DSP_STATUS_OFFSET 8 /* I/F blk offset to DSP Status */ +#define VERSION_ID_OFFSET 9 /* I/F blk offset to G.PAK Version Id */ +#define MAX_CMD_MSG_LEN_OFFSET 10 /* I/F blk offset to Max Cmd Msg Length */ +#define CMD_MSG_LEN_OFFSET 11 /* I/F blk offset to Command Msg Length */ +#define REPLY_MSG_LEN_OFFSET 12 /* I/F blk offset to Reply Msg Length */ +#define NUM_CHANNELS_OFFSET 13 /* I/F blk offset to Num Built Channels */ +#define NUM_PKT_CHANNELS_OFFSET 14 /* I/F blk offset to Num Pkt Channels */ +#define NUM_CONFERENCES_OFFSET 15 /* I/F blk offset to Num Conferences */ +//#define CPU_USAGE_OFFSET_1MS 16 /* I/F blk offset to CPU Usage statistics */ +#define CPU_USAGE_OFFSET 18 /* I/F blk offset to CPU Usage statistics */ +//#define CPU_USAGE_OFFSET_10MS 20 /* I/F blk offset to CPU Usage statistics */ +#define FRAMING_STATS_OFFSET 22 /* I/F blk offset to Framing statistics */ + +//#define GPAK_RELEASE_Rate rate10ms +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +// Macro to reconstruct a 32-bit value from two 16-bit values. +// Parameter p32: 32-bit-wide destination +// Parameter p16: 16-bit-wide source array of length 2 words +#define RECONSTRUCT_LONGWORD(p32, p16) p32 = (DSP_ADDRESS)p16[0]<<16; \ + p32 |= (unsigned long)p16[1] +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +/* DSP Status value definitions. */ +#define DSP_INIT_STATUS 0x5555 /* DSP Initialized status value */ +#define HOST_INIT_STATUS 0xAAAA /* Host Initialized status value */ + +/* Circular packet buffer information structure offsets. */ +#define CB_BUFR_BASE 0 /* pointer to base of circular buffer */ +#define CB_BUFR_SIZE 2 /* size of buffer (words) */ +#define CB_BUFR_PUT_INDEX 3 /* offset in buffer for next write */ +#define CB_BUFR_TAKE_INDEX 4 /* offset in buffer for next read */ +#define CIRC_BUFFER_INFO_STRUCT_SIZE 6 + +/* Miscellaneous definitions. */ +#define MSG_BUFFER_SIZE 100 /* size (words) of Host msg buffer */ +#define WORD_BUFFER_SIZE 84 /* size of DSP Word buffer (words) */ + +#ifdef __TMS320C55XX__ // debug sections if not on host +#pragma DATA_SECTION(pDspIfBlk,"GPAKAPIDEBUG_SECT") +#pragma DATA_SECTION(MaxCmdMsgLen,"GPAKAPIDEBUG_SECT") +#pragma DATA_SECTION(MaxChannels,"GPAKAPIDEBUG_SECT") +#pragma DATA_SECTION(DlByteBufr,"GPAKAPIDEBUG_SECT") +#pragma DATA_SECTION(DlWordBufr,"GPAKAPIDEBUG_SECT") +#pragma DATA_SECTION(pEventFifoAddress,"GPAKAPIDEBUG_SECT") +#endif + +/* Host variables related to Host to DSP interface. */ +static DSP_ADDRESS pDspIfBlk[MAX_DSP_CORES]; /* DSP address of I/F block */ +static DSP_WORD MaxCmdMsgLen[MAX_DSP_CORES]; /* max Cmd msg length (octets) */ +static unsigned short int MaxChannels[MAX_DSP_CORES]; /* max num channels */ + +//static unsigned short int MaxPktChannels[MAX_DSP_CORES]; /* max num pkt channels */ +//static unsigned short int MaxConfs[MAX_DSP_CORES]; /* max num conferences */ +//static DSP_ADDRESS pPktInBufr[MAX_DSP_CORES][MAX_PKT_CHANNELS]; /* Pkt In buffer */ +//static DSP_ADDRESS pPktOutBufr[MAX_DSP_CORES][MAX_PKT_CHANNELS]; /* Pkt Out buffer */ +static DSP_ADDRESS pEventFifoAddress[MAX_DSP_CORES]; /* event fifo */ + +static unsigned char DlByteBufr[DOWNLOAD_BLOCK_SIZE * 2]; /* Dowload byte buf */ +static DSP_WORD DlWordBufr[DOWNLOAD_BLOCK_SIZE]; /* Dowload word buffer */ + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * CheckDspReset - Check if the DSP was reset. + * + * FUNCTION + * This function determines if the DSP was reset and is ready. If reset + * occurred, it reads interface parameters and calculates DSP addresses. + * + * RETURNS + * -1 = DSP is not ready. + * 0 = Reset did not occur. + * 1 = Reset occurred. + * + */ +static int CheckDspReset( + int DspId /* DSP Identifier (0 to MaxDSPCores-1) */ + ) +{ + DSP_ADDRESS IfBlockPntr; /* Interface Block pointer */ + DSP_WORD DspStatus; /* DSP Status */ + DSP_WORD DspChannels; /* number of DSP channels */ + DSP_WORD DspConfs; /* number of DSP conferences */ + DSP_ADDRESS PktBufrMem; /* address of Packet Buffer */ + DSP_WORD Temp[2]; + unsigned short int i; /* loop index / counter */ + + /* Read the pointer to the Interface Block. */ + gpakReadDspMemory(DspId, DSP_IFBLK_ADDRESS, 2, Temp); + RECONSTRUCT_LONGWORD(IfBlockPntr, Temp); + + /* If the pointer is zero, return with an indication the DSP is not + ready. */ + if (IfBlockPntr == 0) + return (-1); + + /* Read the DSP's Status. */ + gpakReadDspMemory(DspId, IfBlockPntr + DSP_STATUS_OFFSET, 1, &DspStatus); + + /* If status indicates the DSP was reset, read the DSP's interface + parameters and calculate DSP addresses. */ + if (DspStatus == DSP_INIT_STATUS || + ((DspStatus == HOST_INIT_STATUS) && (pDspIfBlk[DspId] == 0))) + { + /* Save the address of the DSP's Interface Block. */ + pDspIfBlk[DspId] = IfBlockPntr; + + /* Read the DSP's interface parameters. */ + gpakReadDspMemory(DspId, IfBlockPntr + MAX_CMD_MSG_LEN_OFFSET, 1, + &(MaxCmdMsgLen[DspId])); + + /* read the number of configured DSP channels */ + gpakReadDspMemory(DspId, IfBlockPntr + NUM_CHANNELS_OFFSET, 1, + &DspChannels); + if (DspChannels > MAX_CHANNELS) + MaxChannels[DspId] = MAX_CHANNELS; + else + MaxChannels[DspId] = (unsigned short int) DspChannels; +#if 0 + /* read the number of configured DSP conferences */ + gpakReadDspMemory(DspId, IfBlockPntr + NUM_CONFERENCES_OFFSET, 1, + &DspConfs); + if (DspConfs > MAX_CONFS) + MaxConfs[DspId] = MAX_CONFS; + else + MaxConfs[DspId] = (unsigned short int) DspConfs; + + + /* read the number of configured DSP packet channels */ + gpakReadDspMemory(DspId, IfBlockPntr + NUM_PKT_CHANNELS_OFFSET, 1, + &DspChannels); + if (DspChannels > MAX_PKT_CHANNELS) + MaxPktChannels[DspId] = MAX_PKT_CHANNELS; + else + MaxPktChannels[DspId] = (unsigned short int) DspChannels; + + + /* read the pointer to the circular buffer infor struct table */ + gpakReadDspMemory(DspId, IfBlockPntr + PKT_BUFR_MEM_OFFSET, 2, Temp); + RECONSTRUCT_LONGWORD(PktBufrMem, Temp); + + + /* Determine the addresses of each channel's Packet buffers. */ + for (i = 0; i < MaxPktChannels[DspId]; i++) + { + pPktInBufr[DspId][i] = PktBufrMem; + pPktOutBufr[DspId][i] = PktBufrMem + CIRC_BUFFER_INFO_STRUCT_SIZE; + PktBufrMem += (CIRC_BUFFER_INFO_STRUCT_SIZE*2); + } +#endif + + /* read the pointer to the event fifo info struct */ + gpakReadDspMemory(DspId, IfBlockPntr + EVENT_MSG_PNTR_OFFSET, 2, Temp); + RECONSTRUCT_LONGWORD(pEventFifoAddress[DspId], Temp); + + /* Set the DSP Status to indicate the host recognized the reset. */ + DspStatus = HOST_INIT_STATUS; + gpakWriteDspMemory(DspId, IfBlockPntr + DSP_STATUS_OFFSET, 1, + &DspStatus); + + /* Return with an indication that a reset occurred. */ + return (1); + } + + /* If status doesn't indicate the host recognized a reset, return with an + indication the DSP is not ready. */ + if ((DspStatus != HOST_INIT_STATUS) || (pDspIfBlk[DspId] == 0)) + return (-1); + + /* Return with an indication that a reset did not occur. */ + return (0); +} + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * WriteDspCmdMessage - Write a Host Command/Request message to DSP. + * + * FUNCTION + * This function writes a Host Command/Request message into DSP memory and + * informs the DSP of the presence of the message. + * + * RETURNS + * -1 = Unable to write message (msg len or DSP Id invalid or DSP not ready) + * 0 = Temporarily unable to write message (previous Cmd Msg busy) + * 1 = Message written successfully + * + */ +static int WriteDspCmdMessage( + int DspId, /* DSP Identifier (0 to MaxDSPCores-1) */ + DSP_WORD *pMessage, /* pointer to Command message */ + DSP_WORD MsgLength /* length of message (octets) */ + ) +{ + DSP_WORD CmdMsgLength; /* current Cmd message length */ + DSP_WORD Temp[2]; + DSP_ADDRESS BufferPointer; /* message buffer pointer */ + + /* Check if the DSP was reset and is ready. */ + if (CheckDspReset(DspId) == -1) + return (-1); + + /* Make sure the message length is valid. */ + if ((MsgLength < 1) || (MsgLength > MaxCmdMsgLen[DspId])) + return (-1); + + /* Make sure a previous Command message is not in use by the DSP. */ + gpakReadDspMemory(DspId, pDspIfBlk[DspId] + CMD_MSG_LEN_OFFSET, 1, + &CmdMsgLength); + if (CmdMsgLength != 0) + return (0); + + /* Purge any previous Reply message that wasn't read. */ + gpakWriteDspMemory(DspId, pDspIfBlk[DspId] + REPLY_MSG_LEN_OFFSET, 1, + &CmdMsgLength); + + /* Copy the Command message into DSP memory. */ + gpakReadDspMemory(DspId, pDspIfBlk[DspId] + CMD_MSG_PNTR_OFFSET, 2, Temp); + RECONSTRUCT_LONGWORD(BufferPointer, Temp); + gpakWriteDspMemory(DspId, BufferPointer, (MsgLength + 1) / 2, pMessage); + + /* Store the message length in DSP's Command message length (flags DSP that + a Command message is ready). */ + CmdMsgLength = MsgLength; + gpakWriteDspMemory(DspId, pDspIfBlk[DspId] + CMD_MSG_LEN_OFFSET, 1, + &CmdMsgLength); + + /* Return with an indication the message was written. */ + return (1); +} + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * ReadDspReplyMessage - Read a DSP Reply message from DSP. + * + * FUNCTION + * This function reads a DSP Reply message from DSP memory. + * + * RETURNS + * -1 = Unable to write message (msg len or DSP Id invalid or DSP not ready) + * 0 = No message available (DSP Reply message empty) + * 1 = Message read successfully (message and length stored in variables) + * + */ +static int ReadDspReplyMessage( + int DspId, /* DSP Identifier (0 to MaxDSPCores-1) */ + DSP_WORD *pMessage, /* pointer to Reply message buffer */ + DSP_WORD *pMsgLength /* pointer to msg length var (octets) */ + ) +{ + DSP_WORD MsgLength; /* message length */ + DSP_ADDRESS BufferPointer; /* message buffer pointer */ + DSP_WORD Temp[2]; + + /* Check if the DSP was reset and is ready. */ + if (CheckDspReset(DspId) == -1) + return (-1); + + /* Check if a Reply message is ready. */ + gpakReadDspMemory(DspId, pDspIfBlk[DspId] + REPLY_MSG_LEN_OFFSET, 1, + &MsgLength); + if (MsgLength == 0) + return (0); + + /* Make sure the message length is valid. */ + if (MsgLength > *pMsgLength) + return (-1); + + /* Copy the Reply message from DSP memory. */ + gpakReadDspMemory(DspId, pDspIfBlk[DspId] + REPLY_MSG_PNTR_OFFSET, 2, Temp); + RECONSTRUCT_LONGWORD(BufferPointer, Temp); + gpakReadDspMemory(DspId, BufferPointer, (MsgLength + 1) / 2, pMessage); + + /* Store the message length in the message length variable. */ + *pMsgLength = MsgLength; + + /* Indicate a Reply message is not ready. */ + MsgLength = 0; + gpakWriteDspMemory(DspId, pDspIfBlk[DspId] + REPLY_MSG_LEN_OFFSET, 1, + &MsgLength); + + /* Return with an indication the message was read. */ + return (1); +} + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * ReadCircBuffer - Read from a DSP circular buffer. + * + * FUNCTION + * This function reads a block of words from a DSP circular buffer. The Take + * address is incremented by the number of words read adjusting for buffer + * wrap. + * + * RETURNS + * nothing + * + */ +static void ReadCircBuffer( + int DspId, /* DSP Identifier (0 to MaxDSPCores-1) */ + DSP_ADDRESS BufrBaseAddress, /* address of base of circular buffer */ + DSP_ADDRESS BufrLastAddress, /* address of last word in buffer */ + DSP_ADDRESS *TakeAddress, /* pointer to address in buffer for read */ + DSP_WORD *pWordBuffer, /* pointer to buffer for words read */ + DSP_WORD NumWords /* number of words to read */ + ) +{ + DSP_WORD WordsTillEnd; /* number of words until end of buffer */ + + /* Determine the number of words from the start address until the end of the + buffer. */ + WordsTillEnd = BufrLastAddress - *TakeAddress + 1; + + /* If a buffer wrap will occur, read the first part at the end of the + buffer followed by the second part at the beginning of the buffer. */ + if (NumWords > WordsTillEnd) + { + gpakReadDspMemory(DspId, *TakeAddress, WordsTillEnd, pWordBuffer); + gpakReadDspMemory(DspId, BufrBaseAddress, NumWords - WordsTillEnd, + &(pWordBuffer[WordsTillEnd])); + *TakeAddress = BufrBaseAddress + NumWords - WordsTillEnd; + } + + /* If a buffer wrap will not occur, read all words starting at the current + take address in the buffer. */ + else + { + gpakReadDspMemory(DspId, *TakeAddress, NumWords, pWordBuffer); + if (NumWords == WordsTillEnd) + *TakeAddress = BufrBaseAddress; + else + *TakeAddress = *TakeAddress + NumWords; + } + return; +} + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * VerifyReply - Verify the reply message is correct for the command sent. + * + * FUNCTION + * This function verifies correct reply message content for the command that + * was just sent. + * + * RETURNS + * 0 = Incorrect + * 1 = Correct + * + */ +static int VerifyReply( + DSP_WORD *pMsgBufr, /* pointer to Reply message buffer */ + int CheckType, /* reply check type */ + DSP_WORD CheckValue /* reply check value */ + ) +{ + + /* Verify Channel or Conference Id. */ + if (CheckType == 1) + { + if (((pMsgBufr[1] >> 8) & 0xFF) != CheckValue) + return (0); + } + + /* Verify Test Mode Id. */ + else if (CheckType == 2) + { + if (pMsgBufr[1] != CheckValue) + return (0); + } + + /* Return with an indication of correct reply. */ + return (1); +} + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * TransactCmd - Send a command to the DSP and receive it's reply. + * + * FUNCTION + * This function sends the specified command to the DSP and receives the DSP's + * reply. + * + * RETURNS + * Length of reply message (0 = Failure) + * + */ +static unsigned int TransactCmd( + int DspId, /* DSP Identifier (0 to MaxDSPCores-1) */ + DSP_WORD *pMsgBufr, /* pointer to Cmd/Reply message buffer */ + DSP_WORD CmdLength, /* length of command message (octets) */ + DSP_WORD ReplyType, /* required type of reply message */ + DSP_WORD ReplyLength, /* required length of reply message (octets) */ + int ReplyCheckType, /* reply check type */ + DSP_WORD ReplyCheckValue /* reply check value */ + ) +{ + int FuncStatus; /* function status */ + int LoopCount; /* wait loop counter */ + DSP_WORD RcvReplyLength; /* received Reply message length */ + DSP_WORD RcvReplyType; /* received Reply message type code */ + DSP_WORD RetValue; /* return value */ + + /* Default the return value to indicate a failure. */ + RetValue = 0; + + /* Lock access to the DSP. */ + gpakLockAccess(DspId); + + /* Attempt to write the command message to the DSP. */ + LoopCount = 0; + while ((FuncStatus = WriteDspCmdMessage(DspId, pMsgBufr, CmdLength)) != 1) + { + if (FuncStatus == -1) + break; + if (++LoopCount > MAX_WAIT_LOOPS) + break; + gpakHostDelay(); + } + + /* Attempt to read the reply message from the DSP if the command message was + sent successfully. */ + if (FuncStatus == 1) + { + for (LoopCount = 0; LoopCount < MAX_WAIT_LOOPS; LoopCount++) + { + RcvReplyLength = MSG_BUFFER_SIZE * 2; + FuncStatus = ReadDspReplyMessage(DspId, pMsgBufr, &RcvReplyLength); + if (FuncStatus == 1) + { + RcvReplyType = (pMsgBufr[0] >> 8) & 0xFF; + if ((RcvReplyLength >= ReplyLength) && + (RcvReplyType == ReplyType) && + VerifyReply(pMsgBufr, ReplyCheckType, ReplyCheckValue)) + { + RetValue = RcvReplyLength; + break; + } + else if (RcvReplyType == MSG_NULL_REPLY) + break; + } + else if (FuncStatus == -1) + break; + gpakHostDelay(); + } + } + + /* Unlock access to the DSP. */ + gpakUnlockAccess(DspId); + + /* Return the length of the reply message (0 = failure). */ + return (RetValue); +} + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * gpakConfigurePorts - Configure a DSP's serial ports. + * + * FUNCTION + * This function configures a DSP's serial ports. + * + * RETURNS + * Status code indicating success or a specific error. + * + */ +gpakConfigPortStatus_t gpakConfigurePorts( + unsigned short int DspId, /* DSP Id (0 to MaxDSPCores-1) */ + GpakPortConfig_t *pPortConfig, /* pointer to Port Config info */ + GPAK_PortConfigStat_t *pStatus /* pointer to Port Config Status */ + ) +{ + DSP_WORD MsgBuffer[MSG_BUFFER_SIZE]; /* message buffer */ + + /* Make sure the DSP Id is valid. */ + if (DspId >= MAX_DSP_CORES) + return (CpsInvalidDsp); + + /* Build the Configure Serial Ports message. */ + MsgBuffer[0] = MSG_CONFIGURE_PORTS << 8; + MsgBuffer[1] = (DSP_WORD) + ((pPortConfig->SlotsSelect1 << 12) | + ((pPortConfig->FirstBlockNum1 << 8) & 0x0F00) | + ((pPortConfig->SecBlockNum1 << 4) & 0x00F0)); + MsgBuffer[2] = (DSP_WORD) pPortConfig->FirstSlotMask1; + MsgBuffer[3] = (DSP_WORD) pPortConfig->SecSlotMask1; + MsgBuffer[4] = (DSP_WORD) + ((pPortConfig->SlotsSelect2 << 12) | + ((pPortConfig->FirstBlockNum2 << 8) & 0x0F00) | + ((pPortConfig->SecBlockNum2 << 4) & 0x00F0)); + MsgBuffer[5] = (DSP_WORD) pPortConfig->FirstSlotMask2; + MsgBuffer[6] = (DSP_WORD) pPortConfig->SecSlotMask2; + MsgBuffer[7] = (DSP_WORD) + ((pPortConfig->SlotsSelect3 << 12) | + ((pPortConfig->FirstBlockNum3 << 8) & 0x0F00) | + ((pPortConfig->SecBlockNum3 << 4) & 0x00F0)); + MsgBuffer[8] = (DSP_WORD) pPortConfig->FirstSlotMask3; + MsgBuffer[9] = (DSP_WORD) pPortConfig->SecSlotMask3; + + MsgBuffer[10] = (DSP_WORD) + (((pPortConfig->DxDelay1 << 11) & 0x0800) | + ((pPortConfig->RxDataDelay1 << 9) & 0x0600) | + ((pPortConfig->TxDataDelay1 << 7) & 0x0180) | + ((pPortConfig->RxClockPolarity1 << 6) & 0x0040) | + ((pPortConfig->TxClockPolarity1 << 5) & 0x0020) | + ((pPortConfig->RxFrameSyncPolarity1 << 4) & 0x0010) | + ((pPortConfig->TxFrameSyncPolarity1 << 3) & 0x0008) | + ((pPortConfig->CompandingMode1 << 1) & 0x0006) | + (pPortConfig->SerialWordSize1 & 0x0001)); + + MsgBuffer[11] = (DSP_WORD) + (((pPortConfig->DxDelay2 << 11) & 0x0800) | + ((pPortConfig->RxDataDelay2 << 9) & 0x0600) | + ((pPortConfig->TxDataDelay2 << 7) & 0x0180) | + ((pPortConfig->RxClockPolarity2 << 6) & 0x0040) | + ((pPortConfig->TxClockPolarity2 << 5) & 0x0020) | + ((pPortConfig->RxFrameSyncPolarity2 << 4) & 0x0010) | + ((pPortConfig->TxFrameSyncPolarity2 << 3) & 0x0008) | + ((pPortConfig->CompandingMode2 << 1) & 0x0006) | + (pPortConfig->SerialWordSize1 & 0x0001)); + + MsgBuffer[12] = (DSP_WORD) + (((pPortConfig->DxDelay3 << 11) & 0x0800) | + ((pPortConfig->RxDataDelay3 << 9) & 0x0600) | + ((pPortConfig->TxDataDelay3 << 7) & 0x0180) | + ((pPortConfig->RxClockPolarity3 << 6) & 0x0040) | + ((pPortConfig->TxClockPolarity3 << 5) & 0x0020) | + ((pPortConfig->RxFrameSyncPolarity3 << 4) & 0x0010) | + ((pPortConfig->TxFrameSyncPolarity3 << 3) & 0x0008) | + ((pPortConfig->CompandingMode3 << 1) & 0x0006) | + (pPortConfig->SerialWordSize3 & 0x0001)); + + MsgBuffer[13] = (DSP_WORD) pPortConfig->ThirdSlotMask1; + MsgBuffer[14] = (DSP_WORD) pPortConfig->FouthSlotMask1; + MsgBuffer[15] = (DSP_WORD) pPortConfig->FifthSlotMask1; + MsgBuffer[16] = (DSP_WORD) pPortConfig->SixthSlotMask1; + MsgBuffer[17] = (DSP_WORD) pPortConfig->SevenSlotMask1; + MsgBuffer[18] = (DSP_WORD) pPortConfig->EightSlotMask1; + + MsgBuffer[19] = (DSP_WORD) pPortConfig->ThirdSlotMask2;; + MsgBuffer[20] = (DSP_WORD) pPortConfig->FouthSlotMask2; + MsgBuffer[21] = (DSP_WORD) pPortConfig->FifthSlotMask2;; + MsgBuffer[22] = (DSP_WORD) pPortConfig->SixthSlotMask2; + MsgBuffer[23] = (DSP_WORD) pPortConfig->SevenSlotMask2;; + MsgBuffer[24] = (DSP_WORD) pPortConfig->EightSlotMask2; + + MsgBuffer[25] = (DSP_WORD) pPortConfig->ThirdSlotMask3;; + MsgBuffer[26] = (DSP_WORD) pPortConfig->FouthSlotMask3; + MsgBuffer[27] = (DSP_WORD) pPortConfig->FifthSlotMask3;; + MsgBuffer[28] = (DSP_WORD) pPortConfig->SixthSlotMask3; + MsgBuffer[29] = (DSP_WORD) pPortConfig->SevenSlotMask3;; + MsgBuffer[30] = (DSP_WORD) pPortConfig->EightSlotMask3; + + + /* Attempt to send the Configure Serial Ports message to the DSP and receive + it's reply. */ + if (!TransactCmd(DspId, MsgBuffer, 62, MSG_CONFIG_PORTS_REPLY, 4, 0, 0)) + return (CpsDspCommFailure); + + /* Return with an indication of success or failure based on the return + status in the reply message. */ + *pStatus = (GPAK_PortConfigStat_t) (MsgBuffer[1] & 0xFF); + if (*pStatus == Pc_Success) + return (CpsSuccess); + else + return (CpsParmError); +} + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * gpakConfigureChannel - Configure a DSP's Channel. + * + * FUNCTION + * This function configures a DSP's Channel. + * + * RETURNS + * Status code indicating success or a specific error. + * + */ +gpakConfigChanStatus_t gpakConfigureChannel( + unsigned short int DspId, /* DSP Id (0 to MaxDSPCores-1) */ + unsigned short int ChannelId, /* Channel Id (0 to MaxChannels-1) */ + GpakChanType ChannelType, /* Channel Type */ + GpakChannelConfig_t *pChanConfig, /* pointer to Channel Config info */ + GPAK_ChannelConfigStat_t *pStatus /* pointer to Channel Config Status */ + ) +{ + DSP_WORD MsgBuffer[MSG_BUFFER_SIZE]; /* message buffer */ + DSP_WORD MsgLength; /* message length */ + + /* Make sure the DSP Id is valid. */ + if (DspId >= MAX_DSP_CORES) + return (CcsInvalidDsp); + + /* Make sure the Channel Id is valid. */ + if (ChannelId >= MaxChannels[DspId]) + return (CcsInvalidChannel); + + /* Build the Configure Channel message based on the Channel Type. */ + switch (ChannelType) + { + + /* PCM to Packet channel type. */ + case tdmToTdm: + + MsgBuffer[2] = (DSP_WORD) + ((pChanConfig->PcmInPortA << 8) | + (pChanConfig->PcmInSlotA & 0xFF)); + MsgBuffer[3] = (DSP_WORD) + ((pChanConfig->PcmOutPortA << 8) | + (pChanConfig->PcmOutSlotA & 0xFF)); + + MsgBuffer[4] = (DSP_WORD) + ((pChanConfig->PcmInPortB << 8) | + (pChanConfig->PcmInSlotB & 0xFF)); + MsgBuffer[5] = (DSP_WORD) + ((pChanConfig->PcmOutPortB << 8) | + (pChanConfig->PcmOutSlotB & 0xFF)); + + MsgBuffer[6] = (DSP_WORD) + ( + ((pChanConfig->FaxCngDetB <<11) & 0x0800) | + ((pChanConfig->FaxCngDetA <<10) & 0x0400) | + ((pChanConfig->MuteToneB << 9) & 0x0200) | + ((pChanConfig->MuteToneA << 8) & 0x0100) | + ((pChanConfig->FrameRate << 6) & 0x00C0) | + ((pChanConfig->ToneTypesB << 5) & 0x0020) | + ((pChanConfig->ToneTypesA << 4) & 0x0010) | + ((pChanConfig->SoftwareCompand & 3) << 2) | + (pChanConfig->EcanEnableB << 1) | + (pChanConfig->EcanEnableA & 1) + ); + + MsgBuffer[7] = (DSP_WORD) + pChanConfig->EcanParametersA.EcanTapLength; + MsgBuffer[8] = (DSP_WORD) + pChanConfig->EcanParametersA.EcanNlpType; + MsgBuffer[9] = (DSP_WORD) + pChanConfig->EcanParametersA.EcanAdaptEnable; + MsgBuffer[10] = (DSP_WORD) + pChanConfig->EcanParametersA.EcanG165DetEnable; + MsgBuffer[11] = (DSP_WORD) + pChanConfig->EcanParametersA.EcanDblTalkThresh; + MsgBuffer[12] = (DSP_WORD) + pChanConfig->EcanParametersA.EcanNlpThreshold; + MsgBuffer[13] = (DSP_WORD) + pChanConfig->EcanParametersA.EcanNlpConv; + MsgBuffer[14] = (DSP_WORD) + pChanConfig->EcanParametersA.EcanNlpUnConv; + MsgBuffer[15] = (DSP_WORD) + pChanConfig->EcanParametersA.EcanNlpMaxSuppress; + + MsgBuffer[16] = (DSP_WORD) + pChanConfig->EcanParametersA.EcanCngThreshold; + MsgBuffer[17] = (DSP_WORD) + pChanConfig->EcanParametersA.EcanAdaptLimit; + MsgBuffer[18] = (DSP_WORD) + pChanConfig->EcanParametersA.EcanCrossCorrLimit; + MsgBuffer[19] = (DSP_WORD) + pChanConfig->EcanParametersA.EcanNumFirSegments; + MsgBuffer[20] = (DSP_WORD) + pChanConfig->EcanParametersA.EcanFirSegmentLen; + + MsgBuffer[21] = (DSP_WORD) + pChanConfig->EcanParametersB.EcanTapLength; + MsgBuffer[22] = (DSP_WORD) + pChanConfig->EcanParametersB.EcanNlpType; + MsgBuffer[23] = (DSP_WORD) + pChanConfig->EcanParametersB.EcanAdaptEnable; + MsgBuffer[24] = (DSP_WORD) + pChanConfig->EcanParametersB.EcanG165DetEnable; + MsgBuffer[25] = (DSP_WORD) + pChanConfig->EcanParametersB.EcanDblTalkThresh; + MsgBuffer[26] = (DSP_WORD) + pChanConfig->EcanParametersB.EcanNlpThreshold; + MsgBuffer[27] = (DSP_WORD) + pChanConfig->EcanParametersB.EcanNlpConv; + MsgBuffer[28] = (DSP_WORD) + pChanConfig->EcanParametersB.EcanNlpUnConv; + MsgBuffer[29] = (DSP_WORD) + pChanConfig->EcanParametersB.EcanNlpMaxSuppress; + MsgBuffer[30] = (DSP_WORD) + pChanConfig->EcanParametersB.EcanCngThreshold; + MsgBuffer[31] = (DSP_WORD) + pChanConfig->EcanParametersB.EcanAdaptLimit; + MsgBuffer[32] = (DSP_WORD) + pChanConfig->EcanParametersB.EcanCrossCorrLimit; + MsgBuffer[33] = (DSP_WORD) + pChanConfig->EcanParametersB.EcanNumFirSegments; + MsgBuffer[34] = (DSP_WORD) + pChanConfig->EcanParametersB.EcanFirSegmentLen; + + MsgLength = 70; // byte number == 35*2 + break; + + + /* Unknown (invalid) channel type. */ + default: + *pStatus = Cc_InvalidChannelType; + return (CcsParmError); + } + + MsgBuffer[0] = MSG_CONFIGURE_CHANNEL << 8; + MsgBuffer[1] = (DSP_WORD) ((ChannelId << 8) | (ChannelType & 0xFF)); + + /* Attempt to send the Configure Channel message to the DSP and receive it's + reply. */ + if (!TransactCmd(DspId, MsgBuffer, MsgLength, MSG_CONFIG_CHAN_REPLY, 4, 1, + (DSP_WORD) ChannelId)) + return (CcsDspCommFailure); + + /* Return with an indication of success or failure based on the return + status in the reply message. */ + *pStatus = (GPAK_ChannelConfigStat_t) (MsgBuffer[1] & 0xFF); + if (*pStatus == Cc_Success) + return (CcsSuccess); + else + return (CcsParmError); +} + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * gpakTearDownChannel - Tear Down a DSP's Channel. + * + * FUNCTION + * This function tears down a DSP's Channel. + * + * RETURNS + * Status code indicating success or a specific error. + * + */ +gpakTearDownStatus_t gpakTearDownChannel( + unsigned short int DspId, /* DSP Id (0 to MaxDSPCores-1) */ + unsigned short int ChannelId, /* Channel Id (0 to MaxChannels-1) */ + GPAK_TearDownChanStat_t *pStatus /* pointer to Tear Down Status */ + ) +{ + DSP_WORD MsgBuffer[MSG_BUFFER_SIZE]; /* message buffer */ + + /* Make sure the DSP Id is valid. */ + if (DspId >= MAX_DSP_CORES) + return (TdsInvalidDsp); + + /* Make sure the Channel Id is valid. */ + if (ChannelId >= MaxChannels[DspId]) + return (TdsInvalidChannel); + + /* Build the Tear Down Channel message. */ + MsgBuffer[0] = MSG_TEAR_DOWN_CHANNEL << 8; + MsgBuffer[1] = (DSP_WORD) (ChannelId << 8); + + /* Attempt to send the Tear Down Channel message to the DSP and receive it's + reply. */ + if (!TransactCmd(DspId, MsgBuffer, 3, MSG_TEAR_DOWN_REPLY, 4, 1, + (DSP_WORD) ChannelId)) + return (TdsDspCommFailure); + + /* Return with an indication of success or failure based on the return + status in the reply message. */ + *pStatus = (GPAK_TearDownChanStat_t) (MsgBuffer[1] & 0xFF); + if (*pStatus == Td_Success) + return (TdsSuccess); + else + return (TdsError); +} + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * gpakAlgControl - Control an Algorithm. + * + * FUNCTION + * This function controls an Algorithm + * + * RETURNS + * Status code indicating success or a specific error. + * + */ +gpakAlgControlStat_t gpakAlgControl( + unsigned short int DspId, // DSP identifier + unsigned short int ChannelId, // channel identifier + GpakAlgCtrl_t ControlCode, // algorithm control code + GPAK_AlgControlStat_t *pStatus // pointer to return status + ) +{ + DSP_WORD MsgBuffer[MSG_BUFFER_SIZE]; /* message buffer */ + + /* Make sure the DSP Id is valid. */ + if (DspId >= MAX_DSP_CORES) + return (AcInvalidDsp); + + /* Make sure the Channel Id is valid. */ + if (ChannelId >= MaxChannels[DspId]) + return (AcInvalidChannel); + + MsgBuffer[0] = MSG_ALG_CONTROL << 8; + MsgBuffer[1] = (DSP_WORD) ((ChannelId << 8) | (ControlCode & 0xFF)); + + /* Attempt to send the Tear Down Channel message to the DSP and receive it's + reply. */ + //need_reply_len; + if (!TransactCmd(DspId, MsgBuffer, 4, MSG_ALG_CONTROL_REPLY, 4, 1, + (DSP_WORD) ChannelId)) + return (AcDspCommFailure); + + /* Return with an indication of success or failure based on the return + status in the reply message. */ + *pStatus = (GPAK_AlgControlStat_t) (MsgBuffer[1] & 0xFF); + if (*pStatus == Ac_Success) + return (AcSuccess); + else + return (AcParmError); + +} + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * gpakReadEventFIFOMessage - read from the event fifo + * + * FUNCTION + * This function reads a single event from the event fifo if one is available + * + * RETURNS + * Status code indicating success or a specific error. + * + * Notes: This function should be called in a loop until the return status + * indicates that the fifo is empty. + * + * If the event code equals "EventLoopbackTeardownComplete", then the + * contents of *pChannelId hold the coderBlockId that was assigned to + * the loopback coder that was torn down. + */ +gpakReadEventFIFOMessageStat_t gpakReadEventFIFOMessage( + unsigned short int DspId, // DSP identifier + unsigned short int *pChannelId, // pointer to channel identifier + GpakAsyncEventCode_t *pEventCode, // pointer to Event Code + GpakAsyncEventData_t *pEventData // pointer to Event Data Struct + ) +{ + DSP_WORD WordBuffer[WORD_BUFFER_SIZE]; /* DSP words buffer */ + GpakAsyncEventCode_t EventCode; /* DSP's event code */ + DSP_WORD EventDataLength; /* Length of event to read */ + DSP_WORD ChannelId; /* DSP's channel Id */ + DSP_ADDRESS EventInfoAddress; /* address of EventFIFO info structure */ + DSP_ADDRESS BufrBaseAddress; /* base address of EventFIFO buffer */ + DSP_ADDRESS BufrLastAddress; /* last address of EventFIFO buffer */ + DSP_ADDRESS TakeAddress; /* current take address in fifo buffer */ + DSP_WORD BufrSize; /* size (in words) of event FIFO buffer */ + DSP_WORD PutIndex; /* event fifo put index */ + DSP_WORD TakeIndex; /* event fifo take index */ + DSP_WORD WordsReady; /* number words ready for read out of event fifo */ + DSP_WORD EventError; /* flag indicating error with event fifo msg */ + DSP_WORD *pDebugData; /* debug data buffer pointer in event data struct */ + + /* Make sure the DSP Id is valid. */ + if (DspId >= MAX_DSP_CORES) { +#if 0 + printk("Invalid DSP\n"); +#endif + return (RefInvalidDsp); + } + + /* Lock access to the DSP. */ + gpakLockAccess(DspId); + +#if 1 + /* Check if the DSP was reset and is ready. */ + if (CheckDspReset(DspId) == -1) + { + gpakUnlockAccess(DspId); +#if 0 + printk("CheckDspReset failed (DspId %d)\n", DspId); +#endif + return (RefDspCommFailure); + } +#endif + + /* Check if an event message is ready in the DSP. */ + EventInfoAddress = pEventFifoAddress[DspId]; + gpakReadDspMemory(DspId, EventInfoAddress, CIRC_BUFFER_INFO_STRUCT_SIZE, + WordBuffer); + RECONSTRUCT_LONGWORD(BufrBaseAddress, ((DSP_WORD *)&WordBuffer[CB_BUFR_BASE])); + BufrSize = WordBuffer[CB_BUFR_SIZE]; + PutIndex = WordBuffer[CB_BUFR_PUT_INDEX]; + TakeIndex = WordBuffer[CB_BUFR_TAKE_INDEX]; + if (PutIndex >= TakeIndex) + WordsReady = PutIndex - TakeIndex; + else + WordsReady = PutIndex + BufrSize - TakeIndex; + + if (WordsReady < 2) + { + gpakUnlockAccess(DspId); + return (RefNoEventAvail); + } + + /* Read the event header from the DSP's Event FIFO. */ + TakeAddress = BufrBaseAddress + TakeIndex; + BufrLastAddress = BufrBaseAddress + BufrSize - 1; + ReadCircBuffer(DspId, BufrBaseAddress, BufrLastAddress, &TakeAddress, + WordBuffer, 2); + TakeIndex += 2; + if (TakeIndex >= BufrSize) + TakeIndex -= BufrSize; + + ChannelId = (WordBuffer[0] >> 8) & 0xFF; + EventCode = (GpakAsyncEventCode_t)(WordBuffer[0] & 0xFF); + EventDataLength = WordBuffer[1]; + EventError = 0; + + switch (EventCode) + { + case EventToneDetect: + if (EventDataLength > WORD_BUFFER_SIZE) + { + gpakUnlockAccess(DspId); +#if 0 + printk("EventDataLength > WORD_BUFFER_SIZE (%d)\n", EventDataLength); +#endif + return (RefInvalidEvent); + } + ReadCircBuffer(DspId, BufrBaseAddress, BufrLastAddress, &TakeAddress, + WordBuffer, EventDataLength); + pEventData->toneEvent.ToneCode = (GpakToneCodes_t) + (WordBuffer[0] & 0xFF); + pEventData->toneEvent.ToneDuration = WordBuffer[1]; + pEventData->toneEvent.Direction = WordBuffer[2]; + pEventData->toneEvent.DebugToneStatus = WordBuffer[3]; + TakeIndex += EventDataLength; + if (TakeIndex >= BufrSize) + TakeIndex -= BufrSize; + if (EventDataLength != 4) { +#if 0 + printk("EventDataLength != 4 it's %d\n", EventDataLength); +#endif + EventError = 1; + } + break; + + default: +#if 0 + printk("Event Code not in switch\n"); +#endif + EventError = 1; + break; + }; + + /* Update the Take index in the DSP's Packet Out buffer information. */ + gpakWriteDspMemory(DspId, EventInfoAddress + CB_BUFR_TAKE_INDEX, 1, + &TakeIndex); + + /* Unlock access to the DSP. */ + gpakUnlockAccess(DspId); + + if (EventError) + return(RefInvalidEvent); + + *pChannelId = ChannelId; + *pEventCode = EventCode; + return(RefEventAvail); + +} + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * gpakPingDsp - ping the DSP to see if it's alive + * + * FUNCTION + * This function checks if the DSP is still communicating with the host + * and returns the DSP SW version + * + * RETURNS + * Status code indicating success or a specific error. + */ +gpakPingDspStat_t gpakPingDsp( + unsigned short int DspId, // DSP identifier + unsigned short int *pDspSwVersion // DSP software version + ) +{ + DSP_WORD MsgBuffer[MSG_BUFFER_SIZE]; /* message buffer */ + DSP_WORD DspStatus; /* DSP's reply status */ + + /* Make sure the DSP Id is valid. */ + if (DspId >= MAX_DSP_CORES) + return (PngInvalidDsp); + + /* send value of 1, DSP increments it */ + MsgBuffer[0] = (MSG_PING << 8); + + /* Attempt to send the ping message to the DSP and receive it's + reply. */ + if (!TransactCmd(DspId, MsgBuffer, 1, MSG_PING_REPLY, 6, 0, 0)) + return (PngDspCommFailure); + + /* Return with an indication of success or failure based on the return + status in the reply message. */ + DspStatus = (MsgBuffer[1] & 0xFF); + if (DspStatus == 0) + { + *pDspSwVersion = MsgBuffer[2]; + return (PngSuccess); + } + else + return (PngDspCommFailure); +} + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * gpakSerialTxFixedValue - transmit a fixed value on a timeslot + * + * FUNCTION + * This function controls transmission of a fixed value out onto a serial + * port's timeslot. + * + * RETURNS + * Status code indicating success or a specific error. + */ +gpakSerialTxFixedValueStat_t gpakSerialTxFixedValue( + unsigned short int DspId, // DSP identifier + unsigned short int ChannelId, // channel identifier + GpakSerialPort_t PcmOutPort, // PCM Output Serial Port Id + unsigned short int PcmOutSlot, // PCM Output Time Slot + unsigned short int Value, // 16-bit value + GpakActivation State // activation state + ) +{ + DSP_WORD MsgBuffer[MSG_BUFFER_SIZE]; /* message buffer */ + DSP_WORD DspStatus; /* DSP's reply status */ + + /* Make sure the DSP Id is valid. */ + if (DspId >= MAX_DSP_CORES) + return (TfvInvalidDsp); + + /* Make sure the Channel Id is valid. */ + if (ChannelId >= MaxChannels[DspId]) + return (TfvInvalidChannel); + + + /* Build the message. */ + MsgBuffer[0] = MSG_SERIAL_TXVAL << 8; + MsgBuffer[1] = (DSP_WORD) ((ChannelId << 8) | (State & 0xFF)); + MsgBuffer[2] = (DSP_WORD) ((PcmOutPort << 8) | (PcmOutSlot & 0xFF)); + MsgBuffer[3] = (DSP_WORD) Value; + + /* Attempt to send the message to the DSP and receive it's + reply. */ + //need_reply_len; + if (!TransactCmd(DspId, MsgBuffer, 8, MSG_SERIAL_TXVAL_REPLY, 4, + 1, ChannelId)) + return (TfvDspCommFailure); + + /* Return with an indication of success or failure based on the return + status in the reply message. */ + DspStatus = (MsgBuffer[1] & 0xFF); + if (DspStatus == 0) + return (TfvSuccess); + else + return (TfvDspCommFailure); +} + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * gpakControlTdmLoopBack - control a serial port's loopback state + * + * FUNCTION + * This function enables/disables the tdm input to output looback mode on a + * serial port + * + * RETURNS + * Status code indicating success or a specific error. + */ + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ +gpakControlTdmLoopBackStat_t gpakControlTdmLoopBack( + unsigned short int DspId, // DSP identifier + GpakSerialPort_t SerialPort, // Serial Port Id + GpakActivation LoopBackState // Loopback State + ) +{ + DSP_WORD MsgBuffer[MSG_BUFFER_SIZE]; /* message buffer */ + DSP_WORD DspStatus; /* DSP's reply status */ + + /* Make sure the DSP Id is valid. */ + if (DspId >= MAX_DSP_CORES) + return (ClbInvalidDsp); + + /* Build the message. */ + MsgBuffer[0] = MSG_TDM_LOOPBACK << 8; + MsgBuffer[1] = (DSP_WORD) ((SerialPort << 8) | (LoopBackState & 0xFF)); + + /* Attempt to send the message to the DSP and receive it's + reply. */ + //need_reply_len; + if (!TransactCmd(DspId, MsgBuffer, 4, MSG_TDM_LOOPBACK_REPLY, 4, 0, 0)) + return (ClbDspCommFailure); + + /* Return with an indication of success or failure based on the return + status in the reply message. */ + DspStatus = (MsgBuffer[1] & 0xFF); + if (DspStatus == 0) + return (ClbSuccess); + else + return (ClbDspCommFailure); +} + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * gpakReadCpuUsage - Read CPU usage statistics from a DSP. + * + * FUNCTION + * This function reads the CPU usage statistics from a DSP's memory. The + * average CPU usage in units of .1 percent are obtained for each of the frame + * rates. + * + * RETURNS + * Status code indicating success or a specific error. + * + */ +gpakReadCpuUsageStat_t gpakReadCpuUsage( + unsigned short int DspId, // Dsp Identifier + unsigned short int *pPeakUsage, // pointer to peak usage variable + unsigned short int *pPrev1SecPeakUsage // peak usage over previous 1 second + ) +{ + DSP_WORD ReadBuffer[2]; /* DSP read buffer */ + + /* Make sure the DSP Id is valid. */ + if (DspId >= MAX_DSP_CORES) + return (RcuInvalidDsp); + + /* Lock access to the DSP. */ + gpakLockAccess(DspId); + + /* Check if the DSP was reset and is ready. */ + if (CheckDspReset(DspId) == -1) + return (RcuDspCommFailure); + + /* Read the CPU Usage statistics from the DSP. */ + gpakReadDspMemory(DspId, pDspIfBlk[DspId] + CPU_USAGE_OFFSET, 2, + ReadBuffer); + + /* Unlock access to the DSP. */ + gpakUnlockAccess(DspId); + + /* Store the usage statistics in the specified variables. */ + *pPrev1SecPeakUsage = ReadBuffer[0]; + *pPeakUsage = ReadBuffer[1]; + + /* Return with an indication the usage staistics were read successfully. */ + return (RcuSuccess); +} + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * gpakResetCpuUsageStats - reset the cpu usage statistics + * + * FUNCTION + * This function resets the cpu utilization statistics + * + * RETURNS + * Status code indicating success or a specific error. + */ +gpakResetCpuUsageStat_t gpakResetCpuUsageStats( + unsigned short int DspId // DSP identifier + ) +{ + DSP_WORD MsgBuffer[MSG_BUFFER_SIZE]; /* message buffer */ + DSP_WORD DspStatus; /* DSP's reply status */ + + /* Make sure the DSP Id is valid. */ + if (DspId >= MAX_DSP_CORES) + return (RstcInvalidDsp); + + MsgBuffer[0] = (MSG_RESET_USAGE_STATS << 8); + + /* Attempt to send the message to the DSP and receive it's reply. */ + //need_reply_len; + if (!TransactCmd(DspId, MsgBuffer, 2, MSG_RESET_USAGE_STATS_REPLY, 4, 0, 0)) + return (RstcDspCommFailure); + + /* Return with an indication of success or failure based on the return + status in the reply message. */ + DspStatus = (MsgBuffer[1] & 0xFF); + if (DspStatus == 0) + return (RstcSuccess); + else + return (RstcDspCommFailure); +} + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * gpakReadFramingStats + * + * FUNCTION + * This function reads a DSP's framing interrupt statistics + * + * RETURNS + * Status code indicating success or a specific error. + */ +gpakReadFramingStatsStatus_t gpakReadFramingStats( + unsigned short int DspId, // DSP identifier + unsigned short int *pFramingError1Count, // port 1 Framing error count + unsigned short int *pFramingError2Count, // port 2 Framing error count + unsigned short int *pFramingError3Count, // port 3 Framing error count + unsigned short int *pDmaStopErrorCount, // DMA-stoppage error count + unsigned short int *pDmaSlipStatsBuffer // DMA slips count + ) +{ + DSP_WORD ReadBuffer[10]; /* DSP read buffer */ + + /* Make sure the DSP Id is valid. */ + if (DspId >= MAX_DSP_CORES) + return (RfsInvalidDsp); + + /* Lock access to the DSP. */ + gpakLockAccess(DspId); + + /* Check if the DSP was reset and is ready. */ + if (CheckDspReset(DspId) == -1) + return (RfsDspCommFailure); + + /* Read the framing interrupt statistics from the DSP. */ + gpakReadDspMemory(DspId, pDspIfBlk[DspId] + FRAMING_STATS_OFFSET, 10, + ReadBuffer); + + /* Unlock access to the DSP. */ + gpakUnlockAccess(DspId); + + /* Store the framing statistics in the specified variables. */ + *pFramingError1Count = ReadBuffer[0]; + *pFramingError2Count = ReadBuffer[1]; + *pFramingError3Count = ReadBuffer[2]; + *pDmaStopErrorCount = ReadBuffer[3]; + + if(pDmaSlipStatsBuffer != 0) + // If users want to get the DMA slips count + { + pDmaSlipStatsBuffer[0] = ReadBuffer[4]; + pDmaSlipStatsBuffer[1] = ReadBuffer[5]; + pDmaSlipStatsBuffer[2] = ReadBuffer[6]; + pDmaSlipStatsBuffer[3] = ReadBuffer[7]; + pDmaSlipStatsBuffer[4] = ReadBuffer[8]; + pDmaSlipStatsBuffer[5] = ReadBuffer[9]; + + } + /* Return with an indication the statistics were read successfully. */ + return (RfsSuccess); +} + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * gpakResetFramingStats - reset a DSP's framing interrupt statistics + * + * FUNCTION + * This function resets a DSP's framing interrupt statistics + * + * RETURNS + * Status code indicating success or a specific error. + */ +gpakResetFramingStatsStatus_t gpakResetFramingStats( + unsigned short int DspId // DSP identifier + ) +{ + DSP_WORD MsgBuffer[MSG_BUFFER_SIZE]; /* message buffer */ + DSP_WORD DspStatus; /* DSP's reply status */ + + /* Make sure the DSP Id is valid. */ + if (DspId >= MAX_DSP_CORES) + return (RstfInvalidDsp); + + MsgBuffer[0] = (MSG_RESET_FRAME_STATS << 8); + + /* Attempt to send the message to the DSP and receive it's reply. */ + //need_reply_len; + if (!TransactCmd(DspId, MsgBuffer, 2, MSG_RESET_FRAME_STATS_REPLY, 4, 0, 0)) + return (RstfDspCommFailure); + + /* Return with an indication of success or failure based on the return + status in the reply message. */ + DspStatus = (MsgBuffer[1] & 0xFF); + if (DspStatus == 0) + return (RstfSuccess); + else + return (RstfDspCommFailure); +} + +/* + * gpakDownloadDsp - Download a DSP's Program and initialized Data memory. + * + * FUNCTION + * This function reads a DSP's Program and Data memory image from the + * specified file and writes the image to the DSP's memory. + * + * RETURNS + * Status code indicating success or a specific error. + * + */ +gpakDownloadStatus_t gpakDownloadDsp( + unsigned short DspId, /* DSP Identifier (0 to MaxDSPCores-1) */ + GPAK_FILE_ID FileId /* G.PAK Download File Identifier */ + ) +{ + gpakDownloadStatus_t RetStatus; /* function return status */ + int NumRead; /* number of file bytes read */ + DSP_ADDRESS Address; /* DSP address */ + unsigned int WordCount; /* number of words in record */ + unsigned int NumWords; /* number of words to read/write */ + unsigned int i; /* loop index / counter */ + unsigned int j; /* loop index */ + + /* Make sure the DSP Id is valid. */ + if (DspId >= MAX_DSP_CORES) + return (GdlInvalidDsp); + + /* Lock access to the DSP. */ + gpakLockAccess(DspId); + + RetStatus = GdlSuccess; + while (RetStatus == GdlSuccess) + { + + /* Read a record header from the file. */ + NumRead = gpakReadFile(FileId, DlByteBufr, 6); + if (NumRead == -1) + { + RetStatus = GdlFileReadError; + break; + } + if (NumRead != 6) + { + RetStatus = GdlInvalidFile; + break; + } + Address = (((DSP_ADDRESS) DlByteBufr[1]) << 16) | + (((DSP_ADDRESS) DlByteBufr[2]) << 8) | + ((DSP_ADDRESS) DlByteBufr[3]); + WordCount = (((unsigned int) DlByteBufr[4]) << 8) | + ((unsigned int) DlByteBufr[5]); + + /* Check for the End Of File record. */ + if (DlByteBufr[0] == 0xFF) + break; + + /* Verify the record is for a valid memory type. */ + if ((DlByteBufr[0] != 0x00) && (DlByteBufr[0] != 0x01)) + { + RetStatus = GdlInvalidFile; + break; + } + + /* Read a block of words at a time from the file and write to the + DSP's memory .*/ + while (WordCount != 0) + { + if (WordCount < DOWNLOAD_BLOCK_SIZE) + NumWords = WordCount; + else + NumWords = DOWNLOAD_BLOCK_SIZE; + WordCount -= NumWords; + NumRead = gpakReadFile(FileId, DlByteBufr, NumWords * 2); + if (NumRead == -1) + { + RetStatus = GdlFileReadError; + break; + } + if (NumRead != (NumWords * 2)) + { + RetStatus = GdlInvalidFile; + break; + } + for (i = 0, j = 0; i < NumWords; i++, j += 2) + DlWordBufr[i] = (((DSP_WORD) DlByteBufr[j]) << 8) | + ((DSP_WORD) DlByteBufr[j + 1]); + gpakWriteDspMemory(DspId, Address, NumWords, DlWordBufr); + Address += ((DSP_ADDRESS) NumWords); + } + } + + /* Unlock access to the DSP. */ + gpakUnlockAccess(DspId); + + /* Return with an indication of success or failure. */ + return (RetStatus); +} + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * gpakReadCpuUsage - Read CPU usage statistics from a DSP. + * + * FUNCTION + * This function reads the memory map register section of DSP memory. + * + * RETURNS + * Status code indicating success or a specific error. + * + */ +gpakReadDSPMemoryStat_t gpakReadDSPMemoryMap( + unsigned short int DspId, // Dsp Identifier + unsigned short int *pDest, // Buffer on host to hold DSP memory map + DSP_ADDRESS BufrBaseAddress, // DSP memory users want to read out + unsigned short int MemoryLength_Word16 // Length of memory section read out, unit is 16-bit word + ) +{ + DSP_WORD MsgBuffer[MSG_BUFFER_SIZE]; /* message buffer */ + DSP_WORD DspStatus; /* DSP reply's status */ + int i; /* loop index / counter */ + + + /* Make sure the DSP Id is valid. */ + if (DspId >= MAX_DSP_CORES) + return (RmmInvalidDsp); + + /* Verify the message buffer is large enough */ + if (MSG_BUFFER_SIZE < MemoryLength_Word16 ) + return (RmmSizeTooBig); + + MsgBuffer[0] = MSG_READ_DSP_MEMORY << 8; + MsgBuffer[1] = (DSP_WORD) ((BufrBaseAddress >> 16) & 0xFFFF); + MsgBuffer[2] = (DSP_WORD) (BufrBaseAddress & 0xFFFF); + MsgBuffer[3] = (DSP_WORD) MemoryLength_Word16; + + /* Attempt to send the Read memory section message to the DSP and receive it's + reply. */ + //need_reply_len; + if (!TransactCmd(DspId, MsgBuffer, 8, MSG_READ_DSP_MEMORY_REPLY, + (MemoryLength_Word16+2)*2, 0, 0) ) + return (RmmInvalidAddress); + + /* Return with an indication of success or failure based on the return + status in the reply message. */ + DspStatus = (MsgBuffer[1] & 0xFF); + if (DspStatus != 0) + return (RmmFailure); + + for (i = 0; i < MemoryLength_Word16; i++) + pDest[i] = (short int) MsgBuffer[2 + i]; + + + return (RmmSuccess); +} + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * gpakAccessGPIO - change Direction/read/write the GPIO on DSP + * + * FUNCTION + * This function read/write GPIO and change the GPIO direction + * + * + * RETURNS + * Status code indicating success or a specific error. + */ +gpakAccessGPIOStat_t gpakAccessGPIO( + unsigned short int DspId, // DSP identifier + GpakGPIOCotrol_t gpakControlGPIO,// select oeration, changeDIR/write/read + unsigned short int *pGPIOValue // DSP software version + ) +{ + DSP_WORD MsgBuffer[MSG_BUFFER_SIZE]; /* message buffer */ + DSP_WORD DspStatus; /* DSP's reply status */ + + /* Make sure the DSP Id is valid. */ + if (DspId >= MAX_DSP_CORES) + return (GPIOInvalidDsp); + + /* send value of 1, DSP increments it */ + MsgBuffer[0] = (MSG_ACCESSGPIO << 8); + MsgBuffer[1] = (DSP_WORD) ((gpakControlGPIO << 8) | (*pGPIOValue & 0xFF) ); + /* Attempt to send the ping message to the DSP and receive it's + reply. */ + if (!TransactCmd(DspId, MsgBuffer, 4, MSG_ACCESSGPIO_REPLY, 6, 0, 0)) + return (GPIODspCommFailure); + + /* Return with an indication of success or failure based on the return + status in the reply message. */ + DspStatus = (MsgBuffer[1] & 0xFF); + if (DspStatus == 0) + { + *pGPIOValue = MsgBuffer[2]; + return (GPIOSuccess); + } + else + return (GPIODspCommFailure); +} + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * gpakWriteSystemParms - Write a DSP's System Parameters. + * + * FUNCTION + * This function writes a DSP's System Parameters information. + * + * Note: + * Or-together the desired bit-mask #defines that are listed below. Only + * those algorithm parameters whose bit-mask is selected in the UpdateBits + * function parameter will be updated. + * + * RETURNS + * Status code indicating success or a specific error. + * + */ + +gpakWriteSysParmsStatus_t gpakWriteSystemParms( + unsigned short int DspId, // DSP identifier + GpakSystemParms_t *pSysParms, /* pointer to System Parms info var */ + unsigned short int UpdateBits, /* input: flags indicating which parms to update */ + GPAK_SysParmsStat_t *pStatus /* pointer to Write System Parms Status */ + ) +{ + DSP_WORD MsgBuffer[MSG_BUFFER_SIZE]; /* message buffer */ + DSP_WORD DspStatus; /* DSP's reply status */ + + /* Make sure the DSP Id is valid. */ + if (DspId >= MAX_DSP_CORES) + return (WspInvalidDsp); + + /* Build the Write System Parameters message. */ + MsgBuffer[0] = MSG_WRITE_SYS_PARMS << 8; + + if (UpdateBits & DTMF_UPDATE_MASK) + { + MsgBuffer[1] |= DTMF_UPDATE_MASK; + MsgBuffer[8] = (DSP_WORD) pSysParms->MinSigLevel; + MsgBuffer[9] = (DSP_WORD) (pSysParms->FreqDeviation & 0xff); + if (pSysParms->SNRFlag) + MsgBuffer[9] |= (1<<8); + } + + MsgBuffer[10] = (DSP_WORD) 0; + if (UpdateBits & DTMF_TWIST_UPDATE_MASK) + { + MsgBuffer[1] |= DTMF_TWIST_UPDATE_MASK; + MsgBuffer[10] |= (DSP_WORD) (pSysParms->DtmfFwdTwist & 0x000f); + MsgBuffer[10] |= (DSP_WORD) ((pSysParms->DtmfRevTwist << 4) & 0x00f0); + } + + + if (UpdateBits & DTMF_VALID_MASK) + { + MsgBuffer[1] |= DTMF_VALID_MASK; + MsgBuffer[11] = (DSP_WORD) (pSysParms->DtmfValidityMask & 0x00ff); + } + + /* Attempt to send the ping message to the DSP and receive it's + reply. */ + if (!TransactCmd(DspId, MsgBuffer, 24, MSG_WRITE_SYS_PARMS_REPLY, 6, 0, 0)) + return (WspDspCommFailure); + + /* Return with an indication of success or failure based on the return + status in the reply message. */ + *pStatus = (GPAK_SysParmsStat_t) (MsgBuffer[2] ); + + DspStatus = (MsgBuffer[1] & 0xFF); + if (DspStatus == 0) + return (WspSuccess); + else + return (WspDspCommFailure); +} + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * gpakReadSystemParms - Read a DSP's System Parameters. + * + * FUNCTION + * This function reads a DSP's System Parameters information. + * + * RETURNS + * Status code indicating success or a specific error. + * + */ +gpakReadSysParmsStatus_t gpakReadSystemParms( + unsigned short int DspId, // DSP identifier + GpakSystemParms_t *pSysParms /* pointer to System Parms info var */ + ) +{ + + DSP_WORD MsgBuffer[MSG_BUFFER_SIZE]; /* message buffer */ + + /* Make sure the DSP Id is valid. */ + if (DspId >= MAX_DSP_CORES) + return (RspInvalidDsp); + + /* Build the Read System Parameters message. */ + MsgBuffer[0] = MSG_READ_SYS_PARMS << 8; + + /* Attempt to send the ping message to the DSP and receive it's + reply. */ + if (!TransactCmd(DspId, MsgBuffer, 2, MSG_READ_SYS_PARMS_REPLY, 22, 0, 0)) + return (RspDspCommFailure); + + /* Extract the System Parameters information from the message. */ + pSysParms->DtmfValidityMask = (short int)(MsgBuffer[7]) ; + + pSysParms->MinSigLevel = (short int)MsgBuffer[8]; + pSysParms->SNRFlag = (short int)((MsgBuffer[9]>>8) & 0x1); + pSysParms->FreqDeviation = (short int)(MsgBuffer[9] & 0xff); + pSysParms->DtmfFwdTwist = (short int)MsgBuffer[10] & 0x000f; + pSysParms->DtmfRevTwist = (short int)(MsgBuffer[10] >> 4) & 0x000f; + + /* Return with an indication that System Parameters info was obtained. */ + return (RspSuccess); +} -- cgit v1.2.3