dahdi-linux/drivers/dahdi/voicebus/GpakApi.c

1730 lines
63 KiB
C
Raw Normal View History

/*
* 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
*
* This program has been released under the terms of the GPL version 2 by
* permission of Adaptive Digital Technologies, Inc.
*
*/
/*
* See http://www.asterisk.org for more information about
* the Asterisk project. Please do not directly contact
* any of the maintainers of this project for assistance;
* the project provides a web site, mailing lists and IRC
* channels for your use.
*
* This program is free software, distributed under the terms of
* the GNU General Public License Version 2 as published by the
* Free Software Foundation. See the LICENSE file included with
* this program for more details.
*/
#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 Temp[2];
/* 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;
/* 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);
}
static int CheckDspReset(
int DspId /* DSP Identifier (0 to MaxDSPCores-1) */
)
{
int ret;
int retries = 20;
while (--retries) {
ret = __CheckDspReset(DspId);
if (-1 != ret)
return ret;
msleep(5);
}
return ret;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* 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) */
const 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->SerialWordSize2 & 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);
}
EXPORT_SYMBOL(gpakConfigurePorts);
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* 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;
MsgBuffer[35] = (DSP_WORD)
(
((pChanConfig->EcanParametersB.EcanReconvergenceCheckEnable <<5) & 0x20) |
((pChanConfig->EcanParametersA.EcanReconvergenceCheckEnable <<4) & 0x10) |
((pChanConfig->EcanParametersB.EcanTandemOperationEnable <<3) & 0x8) |
((pChanConfig->EcanParametersA.EcanTandemOperationEnable <<2) & 0x4) |
((pChanConfig->EcanParametersB.EcanMixedFourWireMode << 1) & 0x2) |
(pChanConfig->EcanParametersA.EcanMixedFourWireMode & 1)
);
MsgBuffer[36] = (DSP_WORD)
pChanConfig->EcanParametersA.EcanMaxDoubleTalkThres;
MsgBuffer[37] = (DSP_WORD)
pChanConfig->EcanParametersB.EcanMaxDoubleTalkThres;
MsgBuffer[38] = (DSP_WORD)
pChanConfig->EcanParametersA.EcanSaturationLevel;
MsgBuffer[39] = (DSP_WORD)
pChanConfig->EcanParametersB.EcanSaturationLevel;
MsgBuffer[40] = (DSP_WORD)
pChanConfig->EcanParametersA.EcanNLPSaturationThreshold;
MsgBuffer[41] = (DSP_WORD)
pChanConfig->EcanParametersB.EcanNLPSaturationThreshold;
MsgLength = 84; /* byte number == 42*2 */
break;
/* PCM to Packet channel type. */
case tdmToTdmDebug:
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;
MsgBuffer[35] = (DSP_WORD)
(
((pChanConfig->EcanParametersB.EcanReconvergenceCheckEnable << 5) & 0x20) |
((pChanConfig->EcanParametersA.EcanReconvergenceCheckEnable << 4) & 0x10) |
((pChanConfig->EcanParametersB.EcanTandemOperationEnable << 3) & 0x8) |
((pChanConfig->EcanParametersA.EcanTandemOperationEnable << 2) & 0x4) |
((pChanConfig->EcanParametersB.EcanMixedFourWireMode << 1) & 0x2) |
(pChanConfig->EcanParametersA.EcanMixedFourWireMode & 1)
);
MsgBuffer[36] = (DSP_WORD)
pChanConfig->EcanParametersA.EcanMaxDoubleTalkThres;
MsgBuffer[37] = (DSP_WORD)
pChanConfig->EcanParametersB.EcanMaxDoubleTalkThres;
MsgBuffer[38] = (DSP_WORD)
pChanConfig->EcanParametersA.EcanSaturationLevel;
MsgBuffer[39] = (DSP_WORD)
pChanConfig->EcanParametersB.EcanSaturationLevel;
MsgBuffer[40] = (DSP_WORD)
pChanConfig->EcanParametersA.EcanNLPSaturationThreshold;
MsgBuffer[41] = (DSP_WORD)
pChanConfig->EcanParametersB.EcanNLPSaturationThreshold;
MsgBuffer[42] = (DSP_WORD)
pChanConfig->ChannelId_tobe_Debug;
MsgLength = 86; /* byte number == 43*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);
}
EXPORT_SYMBOL(gpakConfigureChannel);
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* 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);
}
EXPORT_SYMBOL(gpakAlgControl);
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* 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 */
/* Make sure the DSP Id is valid. */
if (DspId >= MAX_DSP_CORES)
return (RefInvalidDsp);
/* Lock access to the DSP. */
gpakLockAccess(DspId);
/* Check if the DSP was reset and is ready. */
if (CheckDspReset(DspId) == -1)
{
gpakUnlockAccess(DspId);
return (RefDspCommFailure);
}
/* 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);
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)
EventError = 1;
break;
default:
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);
}
EXPORT_SYMBOL(gpakPingDsp);
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* 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 != NULL) {
/* 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 */
memset(MsgBuffer, 0, sizeof(MsgBuffer));
/* 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);
}