/* * 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 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) #include #else #include #endif #include #include "zaptel.h" #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]; #if 0 DSP_WORD DspConfs; /* number of DSP conferences */ DSP_ADDRESS PktBufrMem; /* address of Packet Buffer */ unsigned short int i; /* loop index / counter */ #endif /* 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 */ #if 0 DSP_WORD *pDebugData; /* debug data buffer pointer in event data struct */ #endif /* 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); #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); }