/** base PCM Module configuration \param pDev - pointer to the device interface \return IFX_SUCCESS if no error, otherwise IFX_ERROR Remark: Use this function where needed to set the base configuration of the Coder Module. This function isn't an IOCTL function This function configures: - PCM Module - PCM Channels */ IFX_LOCAL IFX_int32_t PCM_baseConf (VINETIC_CHANNEL * pCh, IFX_uint8_t nPath) { VINETIC_DEVICE *pDev = pCh->pParent; IFX_int32_t err = IFX_SUCCESS; IFX_int32_t ch = (pCh->nChannel - 1); switch (nPath) { case TAPI_PCM_DSP: err = Con_ConnectPrepare (&pDev->pSigCh[ch].signal, &pDev->pPcmCh[ch].signal, 0); break; case TAPI_PCM_PHONE: if (ch < pDev->nAnaChan) err = Con_ConnectPrepare (&pDev->pAlmCh[ch].signal, &pDev->pPcmCh[ch].signal, 0); break; default: SET_ERROR (ERR_INVALID); return IFX_ERROR; } pDev->pPcmCh[ch].pcm_ch.bit.i2 = ECMD_IX_EMPTY; pDev->pPcmCh[ch].pcm_ch.bit.i3 = ECMD_IX_EMPTY; pDev->pPcmCh[ch].pcm_ch.bit.i4 = ECMD_IX_EMPTY; pDev->pPcmCh[ch].pcm_ch.bit.i5 = ECMD_IX_EMPTY; if (err == IFX_SUCCESS) err = CmdWrite (pDev, pDev->pPcmCh[ch].pcm_ch.value, CMD_PCM_CH_LEN); return err; }
/******************************************************************************* Description: sets CID buffer request size Arguments: pCh - pointer to the channel structure nSize - Cid data size Return: IFX_SUCCESS or IFX_ERROR *******************************************************************************/ IFX_LOCAL IFX_int32_t setBrsCoef (VINETIC_CHANNEL *pCh, IFX_uint8_t nSize) { VINETIC_DEVICE *pDev = pCh->pParent; IFX_uint16_t pCmd [2] = {0}, pCoefs [6] = {0}; IFX_int32_t err = IFX_SUCCESS; /* disable cid sender */ err = Dsp_SetCidSender (pCh, IFX_FALSE); /* read CID coefs and set BRS */ if (err == IFX_SUCCESS) { /* set CID Coef read Command : ch = nResNr */ pCmd [0] = (CMD1_EOP | (pCh->nChannel - 1)); pCmd [1] = ECMD_CID_COEF; /* read CID sender Coefficients */ err = CmdRead (pDev, pCmd, pCoefs, 4); /* set BRS and write back */ if (err == IFX_SUCCESS) { /* overwrite BRS */ if (nSize >= MAX_CID_LOOP_DATA) pCoefs [5] = MAX_CID_LOOP_DATA; else pCoefs [5] = nSize % MAX_CID_LOOP_DATA; /* write coefficients back */ err = CmdWrite (pDev, pCoefs, 4); } } return err; }
static BOOL CmdBroadcast(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request) { /* Fill in the broadcast address as destination */ *((ULONG *)request->ios2_DstAddr) = 0xffffffff; *((UWORD *)(request->ios2_DstAddr + 4)) = 0xffff; /* Queue the write as normal */ return CmdWrite(LIBBASE, request); }
static BOOL CmdBroadcast(struct IOSana2Req *request, struct DevBase *base) { /* Fill in the broadcast address as destination */ *((ULONG *)request->ios2_DstAddr) = 0xffffffff; *((UWORD *)(request->ios2_DstAddr + 4)) = 0xffff; /* Queue the write as normal */ return CmdWrite(request, base); }
/** Write the configuration according to pSigs \param pC - handle to channel structure \param pSigs - handle to input signal array \return IFX_SUCCESS or IFX_ERROR */ int Con_ConfSignals (VINETIC_CHANNEL * pCh, SIGNAL_ARRAY_INPUTS * pSigs) { VINETIC_DEVICE *pDev = pCh->pParent; int err = IFX_SUCCESS; IFX_uint8_t ch = pCh->nChannel - 1; IFXOS_MutexLock (pDev->memberAcc); /* write ALM module channel */ if (pSigs->almChg) { pDev->pAlmCh[ch].ali_ch.bit.i1 = pSigs->alm[0]; pDev->pAlmCh[ch].ali_ch.bit.i2 = pSigs->alm[1]; pDev->pAlmCh[ch].ali_ch.bit.i3 = pSigs->alm[2]; pDev->pAlmCh[ch].ali_ch.bit.i4 = pSigs->alm[3]; pDev->pAlmCh[ch].ali_ch.bit.i5 = pSigs->alm[4]; err = CmdWrite (pDev, pDev->pAlmCh[ch].ali_ch.value, CMD_ALM_CH_LEN); pSigs->almChg = IFX_FALSE; } if (pSigs->codChg) { pDev->pCodCh[ch].cod_ch.bit.i1 = pSigs->cod[0]; pDev->pCodCh[ch].cod_ch.bit.i2 = pSigs->cod[1]; pDev->pCodCh[ch].cod_ch.bit.i3 = pSigs->cod[2]; pDev->pCodCh[ch].cod_ch.bit.i4 = pSigs->cod[3]; pDev->pCodCh[ch].cod_ch.bit.i5 = pSigs->cod[4]; err = CmdWrite (pDev, pDev->pCodCh[ch].cod_ch.value, CMD_COD_CH_LEN); pSigs->codChg = IFX_FALSE; } if (pSigs->sigChg) { pDev->pSigCh[ch].sig_ch.bit.i1 = pSigs->sig[0]; pDev->pSigCh[ch].sig_ch.bit.i2 = pSigs->sig[1]; err = CmdWrite (pDev, pDev->pSigCh[ch].sig_ch.value, CMD_SIG_CH_LEN); pSigs->sigChg = IFX_FALSE; } IFXOS_MutexUnlock (pDev->memberAcc); return err; }
/** Start DTMF generator \param pCh - channel pointer \param pDtmfData - pointer to the DTMF data to send \param nDtmfSize - number of DTMF words to send \param nFG - frequency generation mode (0 = low, 1 = high) \param cbDtmfStatus - callback on DTMF status change (set to IFX_NULL if unused) \param bByteMode - format of pDtmfData (0 = 16bit, 1 = 8bit) \return IFX_SUCCESS/IFX_ERROR \remarks After triggering the DTMF transmission by calling VINETIC_DtmfStart, the transmission will be handled automatically. The DTMF data will be sent on interrupt request and stopped on end of transmission, error or hook event. The callback cbDtmfStatus can be used to track the status of the DTMF transmission. If bByteMode is set, the driver will convert the IFX_char_t data to DTMF words. This Mode only supports restricted DTMF signs 0 to D (no alert tones or pause). Only supports DTMF generator high level timing mode. Note : when ET = 1 : MOD = 0 , FG = 1 (ref FW Spec). If done another way, it leads to CERR in FW. */ IFX_int32_t VINETIC_DtmfStart(VINETIC_CHANNEL *pCh, IFX_uint16_t *pDtmfData, IFX_uint16_t nDtmfWords, IFX_uint32_t nFG, IFX_void_t (*cbDtmfStatus)(VINETIC_CHANNEL *pCh), IFX_boolean_t bByteMode) { IFX_int32_t err = IFX_SUCCESS; VINETIC_DEVICE *pDev = pCh->pParent; VINETIC_DTMF *pDtmf = &pCh->dtmfSend; IFX_uint8_t ch = pCh->nChannel - 1; /* Prevent simultaneous usage of generator resource */ if (++pDtmf->useCnt != 1) { pDtmf->useCnt--; return IFX_ERROR; } /* Store DTMF data in channel structure for non-blocking sending */ pDtmf->nSent = 0; pDtmf->stateCb = cbDtmfStatus; pDtmf->pData = pDtmfData; pDtmf->bByteMode = bByteMode; pDtmf->nWords = nDtmfWords; /* Enable DTMF generator interrupts Note: Allow rising edge interrupts for DTMFG_BUF, DTMFG_REQ, DTMFG_ACK. Allow falling edge interrupts for DTMFG_ACK and mask others. */ err = VINETIC_Host_Set_EdspIntMask (pCh, VIN_EDSP_DTMFG, IFX_FALSE, VIN_DTMFG_BUF_REQ_ACT_MASK, VIN_DTMFG_ACK_MASK); if (err == IFX_SUCCESS) { DTMF_STATUS(DTMF_START); /* Hardcoded settings, disable, ET = 0, MOD = 1, FG from user, A1 = A2 = 01 */ err = Dsp_DtmfGen(pCh, SIG_DTMGGEN_MOD | (SIG_DTMGGEN_FG & (nFG << SIG_DTMGGEN_FG_OF)) | (SIG_DTMGGEN_A1 & (0x01 << SIG_DTMGGEN_A1_OF)) | (SIG_DTMGGEN_A2 & (0x01 << SIG_DTMGGEN_A2_OF)), 0xFFF0, IFX_FALSE); } if (err == IFX_SUCCESS) { pDev->pSigCh[ch].sig_dtmfgen.bit.en = 1; err = CmdWrite(pDev, pDev->pSigCh[ch].sig_dtmfgen.value, CMD_SIG_DTMFGEN_LEN); } return err; }
/** base ALM configuration \param pDev - pointer to the device structure \param nPath - Voice path selected. Either PCM or CODEC \return IFX_SUCCESS if no error, otherwise IFX_ERROR Remark: Use this function where needed to set the base configuration of Analog Line Module. This function isn't an IOCTL function This function configures: - ALI Module - all ALI channels - all ALI NELECs */ IFX_LOCAL IFX_int32_t ALM_baseConf (VINETIC_CHANNEL * pCh, IFX_uint8_t nPath) { VINETIC_DEVICE *pDev = pCh->pParent; IFX_int32_t err = IFX_SUCCESS; IFX_uint8_t ch = (pCh->nChannel - 1); /* configure ALI channels ************************************************ */ memset (&pDev->pAlmCh[ch].ali_ch.value[CMD_HEADER_CNT], 0, CMD_ALM_CH_LEN * 2); pDev->pAlmCh[ch].ali_ch.bit.en = 1; pDev->pAlmCh[ch].ali_ch.bit.gain_r = ALM_GAIN_0DB; pDev->pAlmCh[ch].ali_ch.bit.gain_x = ALM_GAIN_0DB; switch (nPath) { case TAPI_VOICE_CODER: case TAPI_PCM_DSP: /* signal connection */ err = Con_ConnectPrepare (&pDev->pSigCh[ch].signal, &pDev->pAlmCh[ch].signal, ALM_TO_SIG_IN); break; case TAPI_PCM_PHONE: err = Con_ConnectPrepare (&pDev->pPcmCh[ch].signal, &pDev->pAlmCh[ch].signal, 0); break; default: SET_ERROR (ERR_INVALID); return IFX_ERROR; } /* switch it on */ err = CmdWrite (pDev, pDev->pAlmCh[ch].ali_ch.value, CMD_ALM_CH_LEN); #if (VIN_CFG_FEATURES & (VIN_FEAT_VIN_C | VIN_FEAT_VIN_M)) if (pDev->nChipType != VINETIC_TYPE_S) { /* configure ALI NELEC + Lec ressources ******************************* */ if (err == IFX_SUCCESS) err = Dsp_SetNeLec_Alm (pCh, IFX_TRUE, IFX_TRUE); } #endif /* (VIN_CFG_FEATURES & (VIN_FEAT_VIN_C | VIN_FEAT_VIN_M)) */ if (err != IFX_SUCCESS) { TRACE (VINETIC, DBG_LEVEL_HIGH, ("ALM configuration failed\n\r")); } return err; }
/** Write VINETIC command \param pDev - pointer to the device interface \param pCmd - pointer to command data \return IFX_SUCCESS if no error, otherwise IFX_ERROR (return value of CmdWrite) */ IFX_int32_t VINETIC_Write_Cmd (VINETIC_DEVICE * pDev, VINETIC_IO_MB_CMD * pCmd) { IFX_int32_t ret; IFX_uint16_t *pData = (IFX_uint16_t *) pCmd; if ((pData[0] & CMD1_CMD) == CMD1_EOP && (pData[0] & CMD1_RD) != CMD1_RD) { IFXOS_MutexLock (pDev->memberAcc); DispatchCmd (pDev, pData); } ret = CmdWrite (pDev, pData, (pCmd->cmd2 & CMD2_LEN)); if ((pData[0] & CMD1_CMD) == CMD1_EOP) { IFXOS_MutexUnlock (pDev->memberAcc); } return ret; }
/** This service generates an on or off hook event for the low level driver. \param pChannel Handle to TAPI_CONNECTION structure \return Return value according to IFX_return_t - IFX_ERROR if an error occured - IFX_SUCCESS if successful \remarks The hook event then gets to the hook state machine for validation. Depending on the timing of calling this interface also hook flash and pulse dialing can be verified. */ IFX_return_t TAPI_LL_TestLoop (TAPI_CONNECTION *pChannel, IFX_TAPI_TEST_LOOP_t* pLoop) { VINETIC_DEVICE *pDev = pChannel->pDevice; CMD_DCCTL_Debug_t debugCfg; IFX_int32_t err = IFX_SUCCESS; memset (&debugCfg, 0, sizeof (CMD_DCCTL_Debug_t)); debugCfg.CMD = VIN_CMD_ALM; debugCfg.MOD = VIN_MOD_DCCTL; debugCfg.ECMD = CMD_DCCTL_DEBUG; /* read out first */ debugCfg.RW = VIN_CMD_RD; debugCfg.CH = pChannel->nChannel; debugCfg.LENGTH = 5; err = CmdRead (pDev, (IFX_uint16_t *)((IFX_void_t *)&debugCfg), (IFX_uint16_t *)((IFX_void_t *)&debugCfg), 5); if (err != IFX_SUCCESS) goto error; /* enable or disable testloop */ debugCfg.RW = VIN_CMD_WR; if (pLoop->bAnalog) { debugCfg.data1 = 0x0001; debugCfg.data3 |= 0x8040; } else { debugCfg.data1 = 0x0000; debugCfg.data3 &= ~0x0040; } err = CmdWrite (pDev, (IFX_uint16_t *)((IFX_void_t *)&debugCfg), 5); error: return err; }
/** Set RAM address \param pDev - pointer to the device interface \param ram - RAM flag : D_RAM or P_RAM \param StartAddr - RAM sector start address \param StopAddr - RAM sector end address \return IFX_SUCCESS or IFX_ERROR */ IFX_int32_t Dwld_setRAM(VINETIC_DEVICE *pDev, VINETIC_FW_RAM ram, IFX_uint32_t StartAddr, IFX_uint32_t StopAddr) { IFX_int32_t cnt = 0, err = IFX_ERROR; IFX_uint16_t pCmd[6] = {0}; /* set Cmd 1 */ pCmd[0] = CMD1_EOP | MEM_PAGE; /* Set Cmd 2 and Data words */ switch(ram) { case D_RAM: pCmd[1] = ECMD_SET_DRAM_ADR; pCmd[2] = LOWWORD(StartAddr); cnt = 1; if (StopAddr != 0) { pCmd[3] = LOWWORD(StopAddr); cnt = 2; } break; case P_RAM: pCmd[1] = ECMD_SET_PRAM_ADR; pCmd[2] = HIGHWORD(StartAddr); pCmd[3] = LOWWORD(StartAddr); cnt = 2; if (StopAddr != 0) { pCmd[4] = HIGHWORD(StopAddr); pCmd[5] = LOWWORD(StopAddr); cnt = 4; } break; } if (cnt != 0) err = CmdWrite (pDev, pCmd, cnt); return err; }
/** base SIGNALLING Module configuration \param pDev - pointer to the device interface \param nPath - Voice path selected. Either PCM or CODEC \return IFX_SUCCESS if no error, otherwise IFX_ERROR Remark: Use this function where needed to set the base configuration of Signalling Module. This function isn't an IOCTL function This function configures: - SIGNALLING Module - all SIGNALLING Channels - CID, DTMF gen & recv, ATDs, UTDs In case of PCM voice path, the signalling channle isn't yet connected to any PCM Output. This is to be changed later if. Note: the following configuration is suitable for network tone detection : pCmd [2] = (0x8000 | (((0x18 + i) << 8) & 0x3F00)) | (0x11 + i); The switching should be done when this feature is activated by ioctl. this configuration is still in examination. */ IFX_LOCAL IFX_int32_t SIGNL_baseConf (VINETIC_CHANNEL * pCh, IFX_uint8_t nPath) { VINETIC_DEVICE *pDev = pCh->pParent; IFX_uint16_t pCmd[9] = { 0 }; IFX_int32_t err = IFX_SUCCESS; IFX_uint8_t ch = (pCh->nChannel - 1); /* set channel */ pCmd[0] = CMD1_EOP | ch; /* Configure Signalling Channels ***************************************** */ pDev->pSigCh[ch].sig_ch.value[CMD_HEADER_CNT] = 0; pDev->pSigCh[ch].sig_ch.bit.en = 1; pDev->pSigCh[ch].sig_ch.bit.i1 = ECMD_IX_ALM_OUT0 + ch; switch (nPath) { case TAPI_VOICE_CODER: if (ch < pDev->nAnaChan && ch < pDev->nSigCnt) /* EN = 1, i1 = ALI Output ch ch, i2 = Coder Output ch ch */ err = Con_ConnectPrepare (&pDev->pAlmCh[ch].signal, &pDev->pSigCh[ch].signal, 0); if (err == IFX_SUCCESS && ch < pDev->nSigCnt && ch < pDev->nCoderCnt) err = Con_ConnectPrepare (&pDev->pCodCh[ch].signal, &pDev->pSigCh[ch].signal, 0); break; case TAPI_PCM_DSP: if (ch < pDev->nAnaChan && ch < pDev->nSigCnt) /* EN = 1, i1 = ALI Output ch ch, i2 = PCM Output ch ch. First connect the ALM to sig input 1 (implied in con module) */ err = Con_ConnectPrepare (&pDev->pAlmCh[ch].signal, &pDev->pSigCh[ch].signal, 0); if (err == IFX_SUCCESS && ch < pDev->nSigCnt && ch < pDev->nPcmCnt) { err = Con_ConnectPrepare (&pDev->pPcmCh[ch].signal, &pDev->pSigCh[ch].signal, ALM_TO_SIG_IN); } break; case TAPI_PCM_PHONE: default: /* should not happen! */ return IFX_ERROR; } if (err == IFX_SUCCESS) /* switch it on */ err = CmdWrite (pDev, pDev->pSigCh[ch].sig_ch.value, CMD_SIG_CH_LEN); /* set CID Defaults ****************************************************** */ if (err == IFX_SUCCESS) { IFX_uint16_t *pData = pDev->pSigCh[pCh->nChannel - 1].cid_sender; /* EN = 0 , AD = 1, HLEV = 1, V23 = 1, A1 = 1, A2 = 1, CISNR = ch */ pData [2] = (SIG_CID_AD | SIG_CID_HLEV | SIG_CID_V23 | SIG_CID_A1_VOICE | SIG_CID_A2_VOICE | ch); err = CmdWrite (pDev, pData, 1); #ifdef TAPI_CID /* update internal cid configuration structure */ if (err == IFX_SUCCESS) { pCh->pTapiCh->TapiCidConfig.nAutoDeac = (pData[2] & SIG_CID_AD) >> 13;; pCh->pTapiCh->TapiCidConfig.nHlev = (pData[2] & SIG_CID_HLEV) >> 12; pCh->pTapiCh->TapiCidConfig.nSpec = (pData[2] & SIG_CID_V23) >> 11; }
/** base CODER Module configuration \param pDev - pointer to the device interface \return IFX_SUCCESS if no error, otherwise IFX_ERROR Remark: Use this function where needed to set the base configuration of the Coder Module. This function isn't an IOCTL function This function configures: - CODER Module - all CODER Channels - all CODER Jitter Buffers - Coder Channel decoder status and Coder Channel profiles in case of AAL */ IFX_LOCAL IFX_int32_t CODER_baseConf (VINETIC_CHANNEL * pCh) { VINETIC_DEVICE *pDev = pCh->pParent; IFX_uint16_t pCmd[14] = { 0 }; IFX_int32_t err = IFX_SUCCESS, i; IFX_uint8_t ch = (pCh->nChannel - 1); /* Configure Coder Channels RTP or AAL *********************************** */ if (err == IFX_SUCCESS) { if ((pDev->nEdspVers & ECMD_VERS_EDSP_PRT) == ECMD_VERS_EDSP_PRT_AAL) { /* configure AAL profile */ pCmd[1] = ECMD_COD_CHAAL; /* CID = 0x3E */ pCmd[2] = 0x3E00; /* SQNR_INTV = 0x04 for 5.5 ms (G711, ALaw/ULaw - G726, 16Kbps/32 Kbps */ pCmd[3] = COD_CHAAL_SQNR_INTV_5_5MS; /* Formula : LI = (bitrate[Kbps]*pte)/8 - 1 */ /* LI = 0x2B, ENC = 0x03 : G711 ULaw, 64 Kbps */ pCmd[4] = 0xAC03; /* LI = 0x0A, ENC = 0x04 : G726, 16 Kbps, 5.5 ms */ pCmd[5] = 0x2804; /* LI = 0x0x15, ENC = 0x06: G726, 32 Kbps */ pCmd[6] = 0x5406; for (i = 7; i <= 13; i++) pCmd[i] = 0; err = CmdWrite (pDev, pCmd, 12); } } /* Configure Coder Channels ********************************************** */ if (err == IFX_SUCCESS) { /* reset all data fields/bits in the fw message “Coder Channel Speech Compression” to zero. Explicite set to zero is not necessary */ memset (&pDev->pCodCh[ch].cod_ch.value[CMD_HEADER_CNT], 0, (CMD_COD_CH_LEN * 2)); pDev->pCodCh[ch].signal.modified = IFX_TRUE; pDev->pCodCh[ch].cod_ch.value[3] = 0xF700; pDev->pCodCh[ch].cod_ch.bit.codnr = ch; pDev->pCodCh[ch].cod_ch.bit.gain1 = COD_GAIN_0DB; pDev->pCodCh[ch].cod_ch.bit.gain2 = COD_GAIN_0DB; /* store the encoder value local till the coder-module gets enabled and is not muted */ pDev->pCodCh[ch].enc_conf = COD_CH_G711_ULAW_ENC; switch (pDev->nEdspVers & ECMD_VERS_EDSP_PRT) { case ECMD_VERS_EDSP_PRT_AAL: pDev->pCodCh[ch].cod_ch.bit.pte = COD_CH_PTE_5_5MS; break; default: pDev->pCodCh[ch].cod_ch.bit.pte = COD_CH_PTE_10MS; } #ifdef NO_DATA_WIRING pDev->pCodCh[ch].cod_ch.bit.i1 = ECMD_IX_EMPTY; #else /* here use signal2 */ Con_ConnectPrepare (&pDev->pSigCh[ch].signal, &pDev->pCodCh[ch].signal, COD_TO_SIG_IN); #endif /* NO_DATA_WIRING */ /* configure it */ err = CmdWrite (pDev, pDev->pCodCh[ch].cod_ch.value, CMD_COD_CH_LEN); } /* Configure coder channel decoder status to issue interrupts on change of Decoder or Packet time */ if (err == IFX_SUCCESS) { if ((pDev->nEdspVers & ECMD_VERS_EDSP_PRT) == ECMD_VERS_EDSP_PRT_AAL) { /* set cmd 2 */ pCmd[1] = ECMD_COD_CHDECSTAT; /* PTE = 1 (to set with profile), DC = 1 */ pCmd[2] = (COD_CHDECSTAT_PTC | COD_CHDECSTAT_DC); err = CmdWrite (pDev, pCmd, 1); } } #if (VIN_CFG_FEATURES & VIN_FEAT_VOICE) #if (__BYTE_ORDER == __LITTLE_ENDIAN) /* set up little endian mode in firmware */ pCmd[0] = CMD1_EOP; pCmd[1] = ECMD_ENDIAN_CTL; pCmd[2] = ECMD_ENDIAN_LE; err = CmdWrite (pDev, pCmd, 1); #endif /* (__BYTE_ORDER == __LITTLE_ENDIAN) */ #endif /* (VIN_CFG_FEATURES & VIN_FEAT_VOICE) */ if (err != IFX_SUCCESS) { TRACE (VINETIC, DBG_LEVEL_HIGH, ("CODER configuration failed\n\r")); } return err; }
/** Stop and disable DTMF generator \remarks pCh - channel pointer \return IFX_ERROR/IFX_SUCCESS \remarks Stops the DTMF/AT generator with immediate effect */ IFX_int32_t VINETIC_DtmfStop(VINETIC_CHANNEL *pCh, IFX_int32_t nIsr) { #if (VIN_CFG_FEATURES & VIN_FEAT_VOICE) IFX_int32_t err = IFX_SUCCESS; VINETIC_DTMF_STATE status = DTMF_READY; IFX_uint16_t pCmd[3] = {0}; IFX_uint8_t ch = (pCh->nChannel - 1); VINETIC_DEVICE *pDev = pCh->pParent; VINETIC_DTMF *pDtmf = &pCh->dtmfSend; /* it could be that a request wasn't generated after the last transfer. So sent must be updated again. */ pDtmf->nSent += pDtmf->nCurr; if(pDtmf->nSent == pDtmf->nWords) { status = DTMF_READY; } else { status = DTMF_ABORT; } /* Free DTMF string */ pDtmf->pData = NULL; pDtmf->nWords = 0; pDtmf->nSent = 0; pDtmf->nCurr = 0; pDtmf->useCnt--; if (err == IFX_SUCCESS) { pDev->regMRSRE1[ch] |= (SRE1_DTMFG_REQ | SRE1_DTMFG_BUF | SRE1_DTMFG_ACT); pDev->regMFSRE1[ch] |= SRE1_DTMFG_ACT /*| SRE1_DTMFG_BUF*/; pCmd[0] = (CMD1_IOP | ch); pCmd[1] = ((MRSRE1 << 8) | 1); pCmd[2] = pDev->regMRSRE1[ch]; if (nIsr == IFX_FALSE) { err = CmdWrite(pDev, pCmd, 1); } else { err = CmdWriteIsr(pDev, pCmd, 1); } } if (err == IFX_SUCCESS) { pCmd[0] = (CMD1_IOP | ch); pCmd[1] = ((MFSRE1 << 8) | 1); pCmd[2] = pDev->regMFSRE1[ch]; if (nIsr == IFX_FALSE) { err = CmdWrite(pDev, pCmd, 1); } else { err = CmdWriteIsr(pDev, pCmd, 1); } } /* Disable DTMF generator interrupts and generator itself */ /* Stop the DTMF generator: - reactivate event transmission : ET = 1 - Timing must be controlled by the events : MOD = 0 - Frequency generation must be in high level mode : FG = 1 - Adder A and B Configuration shouldn't be changed ! */ err = Dsp_DtmfGen(pCh, (SIG_DTMGGEN_ET | SIG_DTMGGEN_FG) , 0xFF00, IFX_TRUE); /* enable the dtmf generator for event transmission : EN = 1 */ if (err == IFX_SUCCESS) { pDev->pSigCh[ch].sig_dtmfgen.bit.en = 1; err = CmdWriteIsr (pDev, pDev->pSigCh[ch].sig_dtmfgen.value, CMD_SIG_DTMFGEN_LEN); } DTMF_STATUS(status); return err; #else return IFX_ERROR; #endif /* (VIN_CFG_FEATURES & VIN_FEAT_VOICE) */ }
/** Read the VINETIC Command \param pDev - pointer to the device interface \param pCmd - command for the read access \param pData - memory pointer for Data to read including two command words \param nCount - amount of data to read in words, without command header \return IFX_SUCCESS on success, else IFX_ERROR on error Following errors may occur: ERR_NO_FIBXMS, ERR_OBXML_ZERO \remarks Command Write routine is used to write the read command. In this case, the protection against interupts and concurent tasks is done by Command Read routine it self. Refer to Command Write routine for more details about writing commands. If the command write is successfull, command outbox is polled for an amount of data specified by nCount. If less or more data are available in the mailbox, IFX_ERROR is returned. Otherwise data are read from the command outbox. */ IFX_int32_t CmdRead(VINETIC_DEVICE *pDev, IFX_uint16_t *pCmd, IFX_uint16_t *pData, IFX_uint8_t nCount) { IFX_int32_t err = IFX_SUCCESS; IFX_uint8_t nCnt; IFXOS_ASSERT(!(pCmd[0] & CMD1_BC)); /* protect against concurrent task access and VINETIC interrupts */ VIN_HOST_PROTECT(pDev); /* write read command : Only command header is written. */ pCmd[0] |= CMD1_RD; /* clear and fill the length field */ pCmd[1] = ((pCmd[1] & ~CMD2_LEN) | (IFX_uint16_t)nCount); /* increase count with command header */ nCount += CMD_HEADER_CNT; if ((err = CmdWrite(pDev, pCmd, 0)) == IFX_ERROR) { /* release concurrent task and VINETIC interrupt protection */ VIN_HOST_RELEASE(pDev); TRACE(VINETIC, DBG_LEVEL_HIGH, ("VIN%ld: writing read command fails\n\r", pDev->nDevNr)); goto error; } nCnt = nCount; /* wait for data availability in command outbox and, read data. Note: This action should not take too long, so that interrupts will not get lost. */ if ((err = wait_coutbox_data(pDev, &nCnt)) == IFX_SUCCESS) { if (nCnt > nCount) { err = IFX_ERROR; TRACE (VINETIC, DBG_LEVEL_HIGH, ("VIN%ld: more data in command outbox(%d) than expected(%d)\n\r", pDev->nDevNr, nCnt, nCount)); } else { VIN_LL_UNPROT_CMD_MBX_READ(pDev, pData, nCount); if (pDev->err != ERR_OK) err = IFX_ERROR; } } else { /* polling for outbox data timedout */ TRACE (VINETIC, DBG_LEVEL_HIGH, ("VIN%ld: expected read command data not available\n\r", pDev->nDevNr)); SET_ERROR(ERR_NO_DATA); } /* clear read flag to use it afterwards in CmdWrite */ pData[0] &= ~CMD1_RW; /* release concurrent task and VINETIC interrupt protection */ VIN_HOST_RELEASE(pDev); #ifdef EVALUATION { IFX_uint8_t i; TRACE(VINETIC, DBG_LEVEL_LOW,("CmdRead\n\r")); for (i = 0; i < nCount; i++) TRACE(VINETIC, DBG_LEVEL_LOW,("%d : 0x%04X\n\r", i, pCmd [i])); } #endif /* EVALUATION */ error: LOG_RD_CMD(pCmd, pData, nCount, !err ? err : (pDev->err ? pDev->err : err)); return err; }
/** Configure VINETIC Chip for Voice Coder purposes \param pDev - pointer to VINETIC device structure \param nPcmType - PCM Advanced or for application. Not yet in use. \return IFX_SUCCESS or IFX_ERROR \remarks This function configures the chip for voice communication via PCM. The actual configuration is for PCM-S and the parameter nPcmType isn't evaluated . This will be done when the PCM-Standard config will be done. Access to cached firmware messages is protected against concurrent tasks by the share variable mutex */ IFX_int32_t Basic_PcmConf (VINETIC_CHANNEL * pCh, IFX_uint8_t nPcmType) { VINETIC_DEVICE *pDev = pCh->pParent; IFX_uint16_t pCmd[3] = { 0 }; IFX_int32_t err = IFX_SUCCESS; #if (VIN_CFG_FEATURES & (VIN_FEAT_VIN_C | VIN_FEAT_VIN_M)) if ((pDev->nChipType == VINETIC_TYPE_S) && (nPcmType != TAPI_PCM_PHONE)) { /* not supported for S type */ SET_ERROR (ERR_NOTSUPPORTED); return IFX_ERROR; } #endif /* (VIN_CFG_FEATURES & (VIN_FEAT_VIN_C | VIN_FEAT_VIN_M)) */ /* EOP Cmd */ pCmd[0] = CMD1_EOP; if (!(pDev->nDevState & DS_PCM_EN)) { /* configure PCM interface control */ pCmd[1] = ECMD_PCM_CTL; pCmd[2] = PCM_CTL_EN; err = CmdWrite (pDev, pCmd, 1); } if (err != IFX_SUCCESS) return err; /* set PCM module to enabled */ pDev->nDevState |= DS_PCM_EN; if (!(pDev->nDevState & DS_ALM_EN)) { /* configure analog line module */ pCmd[1] = ECMD_ALM_CTL; pCmd[2] = ALM_CTL_EN; err = CmdWrite (pDev, pCmd, 1); } if (err != IFX_SUCCESS) return err; /* set analog line module to enabled */ pDev->nDevState |= DS_ALM_EN; #if (VIN_CFG_FEATURES & (VIN_FEAT_VIN_C | VIN_FEAT_VIN_M)) if (nPcmType == TAPI_PCM_DSP) { if (!(pDev->nDevState & DS_SIG_EN)) { /* configure signaling module */ pCmd[1] = ECMD_SIG_CTL; pCmd[2] = SIG_CTL_EN; err = CmdWrite (pDev, pCmd, 1); } if (err != IFX_SUCCESS) return err; /* set signalling module to enabled */ pDev->nDevState |= DS_SIG_EN; } #endif /* (VIN_CFG_FEATURES & (VIN_FEAT_VIN_C | VIN_FEAT_VIN_M)) */ /* protect fwmsgs against concurrent tasks */ IFXOS_MutexLock (pDev->memberAcc); /* configure ALI for PCM */ if (pCh->nChannel <= pDev->nAnaChan) err = ALM_baseConf (pCh, nPcmType); if (err != IFX_SUCCESS) goto error; /* configure PCM */ if (pCh->nChannel <= pDev->nPcmCnt) err = PCM_baseConf (pCh, nPcmType); #if (VIN_CFG_FEATURES & (VIN_FEAT_VIN_C | VIN_FEAT_VIN_M)) if (err != IFX_SUCCESS) goto error; if (nPcmType == TAPI_PCM_DSP && (pCh->nChannel <= pDev->nSigCnt)) /* Configure Signalling module */ err = SIGNL_baseConf (pCh, TAPI_PCM_DSP); #endif /* (VIN_CFG_FEATURES & (VIN_FEAT_VIN_C | VIN_FEAT_VIN_M)) */ error: IFXOS_MutexUnlock (pDev->memberAcc); if (err == IFX_SUCCESS) err = Con_ConnectConfigure (pDev); return err; }
/** Configure VINETIC Chip according to Tapi settings \param pDev - pointer to VINETIC device structure \return IFX_SUCCESS or IFX_ERROR \remarks This configuration will be done if tapi configuration mode is TAPI_VOICE_CODER Access to cached firmware messages is protected against concurrent tasks by the share variable mutex */ IFX_int32_t Basic_VoIPConf (VINETIC_CHANNEL * pCh) { VINETIC_DEVICE *pDev = pCh->pParent; IFX_int32_t err = IFX_SUCCESS; IFX_uint16_t pCmd[3] = { 0 }; #if (VIN_CFG_FEATURES & VIN_FEAT_VIN_S) if ((pDev->nChipType == VINETIC_TYPE_S) && (pDev->nChipMajorRev == VINETIC_V2x)) { /* not supported for S type */ SET_ERROR (ERR_NOTSUPPORTED); return IFX_ERROR; } #endif /* (VIN_CFG_FEATURES & VIN_FEAT_VIN_S) */ /* EOP Cmd */ pCmd[0] = CMD1_EOP; /* EN = 1 */ pCmd[2] = 0x8000; if (!(pDev->nDevState & DS_COD_EN)) { /* configure Coder Module */ pCmd[1] = ECMD_COD_CTL; err = CmdWrite (pDev, pCmd, 1); if (err == IFX_SUCCESS) /* set coder module to enabled */ pDev->nDevState |= DS_COD_EN; } if (!(pDev->nDevState & DS_ALM_EN)) { /* configure analog line module */ pCmd[1] = ECMD_ALM_CTL; err = CmdWrite (pDev, pCmd, 1); if (err == IFX_SUCCESS) /* set coder module to enabled */ pDev->nDevState |= DS_ALM_EN; } if (!(pDev->nDevState & DS_SIG_EN)) { /* configure signaling module */ pCmd[1] = ECMD_SIG_CTL; err = CmdWrite (pDev, pCmd, 1); if (err == IFX_SUCCESS) /* set coder module to enabled */ pDev->nDevState |= DS_SIG_EN; } #if 1 if (!(pDev->nDevState & DS_PCM_EN)) { /* configure PCM interface control */ pCmd[1] = ECMD_PCM_CTL; pCmd[2] = PCM_CTL_EN; err = CmdWrite (pDev, pCmd, 1); if (err == IFX_SUCCESS) /* set coder module to enabled */ pDev->nDevState |= DS_PCM_EN; } if (err != IFX_SUCCESS) return err; #endif /** \todo quick fix: activate PCM module for possible connections */ /* protect fwmsgs against concurrent tasks */ IFXOS_MutexLock (pDev->memberAcc); /* configure ALI for VoIP */ if (pCh->nChannel <= pDev->nAnaChan) err = ALM_baseConf (pCh, TAPI_VOICE_CODER); /* configure Coder */ if (err == IFX_SUCCESS && (pCh->nChannel <= pDev->nCoderCnt)) err = CODER_baseConf (pCh); /* Configure Signalling module */ if (err == IFX_SUCCESS && (pCh->nChannel <= pDev->nSigCnt)) err = SIGNL_baseConf (pCh, TAPI_VOICE_CODER); /* unlock */ IFXOS_MutexUnlock (pDev->memberAcc); Con_ConnectConfigure (pDev); /* do other settings if every successfull */ if (err == IFX_SUCCESS) { /* save configured coders for later checks */ pCh->pTapiCh->nCodec = getCoder(pDev->pCodCh[pCh->nChannel - 1].enc_conf); } return err; }
VOID ServiceRequest(struct IOSana2Req *request, struct DevBase *base) { BOOL complete; switch(request->ios2_Req.io_Command) { case CMD_READ: complete = CmdRead(request, base); break; case CMD_WRITE: complete = CmdWrite(request, base); break; case CMD_FLUSH: complete = CmdFlush((APTR)request, base); break; case S2_DEVICEQUERY: complete = CmdS2DeviceQuery(request, base); break; case S2_GETSTATIONADDRESS: complete = CmdGetStationAddress(request, base); break; case S2_CONFIGINTERFACE: complete = CmdConfigInterface(request, base); break; case S2_ADDMULTICASTADDRESS: complete = CmdAddMulticastAddresses(request, base); break; case S2_DELMULTICASTADDRESS: complete = CmdDelMulticastAddresses(request, base); break; case S2_MULTICAST: complete = CmdWrite(request, base); break; case S2_BROADCAST: complete = CmdBroadcast(request, base); break; case S2_TRACKTYPE: complete = CmdTrackType(request, base); break; case S2_UNTRACKTYPE: complete = CmdUntrackType(request, base); break; case S2_GETTYPESTATS: complete = CmdGetTypeStats(request, base); break; case S2_GETSPECIALSTATS: complete = CmdGetSpecialStats(request, base); break; case S2_GETGLOBALSTATS: complete = CmdGetGlobalStats(request, base); break; case S2_ONEVENT: complete = CmdOnEvent(request, base); break; case S2_READORPHAN: complete = CmdReadOrphan(request, base); break; case S2_ONLINE: complete = CmdOnline(request, base); break; case S2_OFFLINE: complete = CmdOffline(request, base); break; case NSCMD_DEVICEQUERY: complete = CmdDeviceQuery((APTR)request, base); break; case S2_ADDMULTICASTADDRESSES: complete = CmdAddMulticastAddresses(request, base); break; case S2_DELMULTICASTADDRESSES: complete = CmdDelMulticastAddresses(request, base); break; case P2_GETSIGNALQUALITY: complete = CmdGetSignalQuality(request, base); break; default: complete = CmdInvalid(request, base); } if(complete && ((request->ios2_Req.io_Flags & IOF_QUICK) == 0)) ReplyMsg((APTR)request); ReleaseSemaphore( &((struct DevUnit *)request->ios2_Req.io_Unit)->access_lock); return; }
void handle_request(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request) { BOOL complete; switch(request->ios2_Req.io_Command) { case CMD_READ: complete = CmdRead(LIBBASE, request); break; case CMD_WRITE: case S2_MULTICAST: complete = CmdWrite(LIBBASE, request); break; case CMD_FLUSH: complete = CmdFlush(LIBBASE, (struct IORequest *)request); break; case S2_DEVICEQUERY: complete = CmdS2DeviceQuery(LIBBASE, request); break; case S2_GETSTATIONADDRESS: complete = CmdGetStationAddress(LIBBASE, request); break; case S2_CONFIGINTERFACE: complete = CmdConfigInterface(LIBBASE, request); break; case S2_BROADCAST: complete = CmdBroadcast(LIBBASE, request); break; case S2_TRACKTYPE: complete = CmdTrackType(LIBBASE, request); break; case S2_UNTRACKTYPE: complete = CmdUntrackType(LIBBASE, request); break; case S2_GETTYPESTATS: complete = CmdGetTypeStats(LIBBASE, request); break; case S2_GETGLOBALSTATS: complete = CmdGetGlobalStats(LIBBASE, request); break; case S2_ONEVENT: complete = CmdOnEvent(LIBBASE, request); break; case S2_READORPHAN: complete = CmdReadOrphan(LIBBASE, request); break; case S2_ONLINE: complete = CmdOnline(LIBBASE, request); break; case S2_OFFLINE: complete = CmdOffline(LIBBASE, request); break; case S2_ADDMULTICASTADDRESS: case S2_ADDMULTICASTADDRESSES: complete = CmdAddMulticastAddresses(LIBBASE, request); break; case S2_DELMULTICASTADDRESS: case S2_DELMULTICASTADDRESSES: complete = CmdDelMulticastAddresses(LIBBASE, request); break; case NSCMD_DEVICEQUERY: complete = CmdDeviceQuery(LIBBASE, (struct IOStdReq *)request); break; default: complete = CmdInvalid(LIBBASE, request); } if(complete && (request->ios2_Req.io_Flags & IOF_QUICK) == 0) ReplyMsg((APTR)request); ReleaseSemaphore(&((struct SiS900Unit *)request->ios2_Req.io_Unit)->sis900u_unit_lock); }
/** Start DTMF generator \param pCh - channel pointer \param pDtmfData - pointer to the DTMF data to send \param nDtmfSize - number of DTMF words to send \param nFG - frequency generation mode (0 = low, 1 = high) \param cbDtmfStatus - callback on DTMF status change (set to NULL if unused) \param bByteMode - format of pDtmfData (0 = 16bit, 1 = 8bit) \return IFX_SUCCESS/IFX_ERROR \remarks After triggering the DTMF transmission by calling VINETIC_DtmfStart, the transmission will be handled automatically. The DTMF data will be sent on interrupt request and stopped on end of transmission, error or hook event. The callback cbDtmfStatus can be used to track the status of the DTMF transmission. If bByteMode is set, the driver will convert the IFX_char_t data to DTMF words. This Mode only supports restricted DTMF signs 0 to D (no alert tones or pause). Only supports DTMF generator high level timing mode. Note : when ET = 1 : MOD = 0 , FG = 1 (ref FW Spec). If done another way, it leads to CERR in FW. */ IFX_int32_t VINETIC_DtmfStart(VINETIC_CHANNEL *pCh, IFX_uint16_t *pDtmfData, IFX_uint16_t nDtmfWords, IFX_uint32_t nFG, IFX_void_t (*cbDtmfStatus)(VINETIC_CHANNEL *pCh), IFX_boolean_t bByteMode) { #if (VIN_CFG_FEATURES & VIN_FEAT_VOICE) IFX_int32_t err; VINETIC_DEVICE *pDev = pCh->pParent; VINETIC_DTMF *pDtmf = &pCh->dtmfSend; IFX_uint8_t ch = pCh->nChannel - 1; /* Prevent simultaneous usage of generator resource */ if (++pDtmf->useCnt != 1) { pDtmf->useCnt--; return IFX_ERROR; } /* Store DTMF data in channel structure for non-blocking sending */ pDtmf->nSent = 0; pDtmf->stateCb = cbDtmfStatus; pDtmf->pData = pDtmfData; pDtmf->bByteMode = bByteMode; pDtmf->nWords = nDtmfWords; DTMF_STATUS(DTMF_START); /* Hardcoded settings, disable, ET = 0, MOD = 1, FG from user, A1 = A2 = 01 */ err = Dsp_DtmfGen(pCh, SIG_DTMGGEN_MOD | (SIG_DTMGGEN_FG & (nFG << SIG_DTMGGEN_FG_OF)) | (SIG_DTMGGEN_A1 & (0x01 << SIG_DTMGGEN_A1_OF)) | (SIG_DTMGGEN_A2 & (0x01 << SIG_DTMGGEN_A2_OF)), 0xFFF0, IFX_FALSE); if (err == IFX_SUCCESS) { pDev->pSigCh[ch].sig_dtmfgen.bit.en = 1; err = CmdWrite(pDev, pDev->pSigCh[ch].sig_dtmfgen.value, CMD_SIG_DTMFGEN_LEN); } /* Enable DTMF generator interrupts */ pDev->regMRSRE1[ch] &= ~(SRE1_DTMFG_REQ | SRE1_DTMFG_BUF | SRE1_DTMFG_ACT); pDev->regMFSRE1[ch] &= ~SRE1_DTMFG_ACT /*| SRE1_DTMFG_BUF*/; if (err == IFX_SUCCESS) { err = RegWrite(pDev, CMD1_IOP | ch, &pDev->regMRSRE1[ch],1, MRSRE1); } if (err == IFX_SUCCESS) { err = RegWrite(pDev, (CMD1_IOP | ch), &pDev->regMFSRE1[ch],1, MFSRE1); } return err; #else return IFX_ERROR; #endif /* (VIN_CFG_FEATURES & VIN_FEAT_VOICE) */ }
/** Do low level UTG (Universal Tone Generator) configuration and activation \param pChannel - handle to TAPI_CONNECTION structure \param pSimpleTone - internal simple tone table entry \return IFX_SUCCESS/IFX_ERROR \remarks The selected signalling channel has to be activated before this command can be sent. For the UTG, the coefficients have to be programmed with a seperate command, before the UTG can be activated. The UTG should be inactive when programming the coefficients. The DMTF / AT Generator is overlaid with the tone generator, which means the same resources for the DMTF / AT Generator and the UTG mustn't be active simultaneously! DTMF /AT will be deactivated to avoid simulatenous activation. It is assumed that the UTG is deactive before calling this function which programms UTG coefficients. In case the UTG event interrupt is needed, the calling function should make sure that the DTMD/AT Generator is deactivated before. This function is completely protected to concurrent member access */ IFX_int32_t Tone_UTG_Start (TAPI_CONNECTION *pChannel, IFX_TAPI_TONE_SIMPLE_t const *pSimpleTone, TAPI_TONE_DST dst, IFX_uint8_t utgNum ) { IFX_int32_t ret = IFX_ERROR; #if (VIN_CFG_FEATURES & VIN_FEAT_VOICE) VINETIC_DEVICE *pDev = (VINETIC_DEVICE *)pChannel->pDevice; VINETIC_CHANNEL *pCh = &pDev->pChannel[pChannel->nChannel]; FWM_SIG_UTG* pUtgCmd = &pDev->pSigCh[pChannel->nChannel].utg[utgNum]; IFX_uint16_t pCmdCoef [27] = {0}; IFX_uint8_t utgRes = 0, ch = pCh->nChannel - 1; /* calling function ensures valid parameter */ IFXOS_ASSERT(pSimpleTone != IFX_NULL); /* check utgNum, please note that resources like "utgNum" are counted from #0 */ if (utgNum >= pDev->VinCapabl.nUtgPerCh) { SET_ERROR (ERR_NORESOURCE); return IFX_ERROR; } /* choose utg resource according to the FW capabilities */ if (utgNum == 0) { /* resources #0..#3 for first utg */ utgRes = (IFX_uint8_t)ch; /* Setup UTG1 interrupt masks. Note : Mask rising edge interrupts for VIN_UTG1_ACT_MASK. Allow falling edge interrupts for VIN_UTG1_ACT_MASK. Note: VIN_UTG2_ACT_MASK is overlaid with V2CPE_EDSP1_INT1_DTMFG_ACT For this reason the mask settings are set here within "Tone_UTG_Start"! */ ret = VINETIC_Host_Set_EdspIntMask (pCh, VIN_EDSP_UTG1, IFX_FALSE, 0, VIN_UTG1_ACT_MASK); if (ret == IFX_ERROR) { return IFX_ERROR; } } else if (utgNum == 1) { /* second resource, UTG2, uses different resources as UTG1 */ utgRes = (IFX_uint8_t)(ch + pDev->nSigCnt); /* check whether CID Generator is active, because the status bits for CIS and UTG2 are overlaid => UTG could not be used while CIS is active! */ if (pDev->pSigCh[ch].cid_sender[2] & SIG_CID_EN) { SET_ERROR (ERR_CID_RUNNING); return (IFX_ERROR); } /* Setup UTG2 interrupt masks. Note : Mask rising edge interrupts for VIN_UTG2_ACT_MASK. Allow falling edge interrupts for VIN_UTG2_ACT_MASK. Note: VIN_UTG2_ACT_MASK is overlaid with V2CPE_EDSP1_INT1_CIS_ACT For this reason the mask settings are set here within "Tone_UTG_Start"! */ ret = VINETIC_Host_Set_EdspIntMask (pCh, VIN_EDSP_UTG2, IFX_FALSE, 0, VIN_UTG2_ACT_MASK); if (ret == IFX_ERROR) { return IFX_ERROR; } } else { SET_ERROR (ERR_NORESOURCE); return IFX_ERROR; } memset (pCmdCoef, 0, sizeof(pCmdCoef)); /* prepare command for coefficients */ pCmdCoef [0] = CMD1_EOP | (utgRes & CMD1_CH); pCmdCoef [1] = ECMD_UTG_COEF; /* set the UTG coefficients */ Utg_SetCoeff (pSimpleTone, pCmdCoef); ret = CmdWrite (pDev, pCmdCoef, 25); if (ret == IFX_ERROR) return IFX_ERROR; /* overwrite utg resource number, because here the "overall number" is used */ pUtgCmd->bit.utgnr = (utgRes & CMD1_CH); /* Tone signal injection and muting the voice signal into adder 1 and/or adder 2 */ switch (dst) { case TAPI_TONE_DST_NET: /* put it to adder 1 to network */ pUtgCmd->bit.a1 = SIG_UTG_MUTE; pUtgCmd->bit.a2 = SIG_UTG_NONE; break; case TAPI_TONE_DST_NETLOCAL: /* put it to adder 1 to network and adder 2 for local */ pUtgCmd->bit.a1 = SIG_UTG_MUTE; pUtgCmd->bit.a2 = SIG_UTG_MUTE; break; case TAPI_TONE_DST_LOCAL: case TAPI_TONE_DST_DEFAULT: default: /* play it locally: take adder 2 */ pUtgCmd->bit.a1 = SIG_UTG_NONE; pUtgCmd->bit.a2 = SIG_UTG_MUTE; break; } /* activate the UTG with the tone action previously programmed */ pUtgCmd->bit.sm = 0; pUtgCmd->bit.en = 1; ret = CmdWrite (pDev, pUtgCmd->value, 1); if (ret == IFX_SUCCESS) { /* tone is playing now, so set the state */ pChannel->TapiComplexToneData[utgNum].nToneState = TAPI_CT_ACTIVE; if (pSimpleTone->loop > 0 || pSimpleTone->pause > 0) { /* auto stop after loop or after each generation step */ pUtgCmd->bit.sm = 1; pUtgCmd->bit.en = 0; ret = CmdWrite (pDev, pUtgCmd->value, 1); } } #endif /* (VIN_CFG_FEATURES & VIN_FEAT_VOICE) */ return ret; }
/** Write the configuration according to pSigs \param pC - handle to channel structure \param pSigs - handle to input signal array \return IFX_SUCCESS or IFX_ERROR */ int Con_ConnectConfigure (VINETIC_DEVICE * pDev) { int err = IFX_SUCCESS, ch; VINDSP_MODULE *pMod; IFXOS_MutexLock (pDev->memberAcc); /* write ALM module channel */ for (ch = 0; ch < pDev->nAnaChan; ++ch) { pMod = &pDev->pAlmCh[ch].signal; if (pMod->modified) { pDev->pAlmCh[ch].ali_ch.bit.i1 = pMod->in[0].i; pDev->pAlmCh[ch].ali_ch.bit.i2 = pMod->in[1].i; pDev->pAlmCh[ch].ali_ch.bit.i3 = pMod->in[2].i; pDev->pAlmCh[ch].ali_ch.bit.i4 = pMod->in[3].i; pDev->pAlmCh[ch].ali_ch.bit.i5 = pMod->in[4].i; err = CmdWrite (pDev, pDev->pAlmCh[ch].ali_ch.value, CMD_ALM_CH_LEN); pMod->modified = IFX_FALSE; } } for (ch = 0; ch < pDev->nCoderCnt; ++ch) { pMod = &pDev->pCodCh[ch].signal; if (pMod->modified) { pDev->pCodCh[ch].cod_ch.bit.i1 = pMod->in[0].i; pDev->pCodCh[ch].cod_ch.bit.i2 = pMod->in[1].i; pDev->pCodCh[ch].cod_ch.bit.i3 = pMod->in[2].i; pDev->pCodCh[ch].cod_ch.bit.i4 = pMod->in[3].i; pDev->pCodCh[ch].cod_ch.bit.i5 = pMod->in[4].i; err = CmdWrite (pDev, pDev->pCodCh[ch].cod_ch.value, CMD_COD_CH_LEN); pMod->modified = IFX_FALSE; } } for (ch = 0; ch < pDev->nPcmCnt; ++ch) { pMod = &pDev->pPcmCh[ch].signal; if (pMod->modified) { pDev->pPcmCh[ch].pcm_ch.bit.i1 = pMod->in[0].i; pDev->pPcmCh[ch].pcm_ch.bit.i2 = pMod->in[1].i; pDev->pPcmCh[ch].pcm_ch.bit.i3 = pMod->in[2].i; pDev->pPcmCh[ch].pcm_ch.bit.i4 = pMod->in[3].i; pDev->pPcmCh[ch].pcm_ch.bit.i5 = pMod->in[4].i; err = CmdWrite (pDev, pDev->pPcmCh[ch].pcm_ch.value, CMD_PCM_CH_LEN); pMod->modified = IFX_FALSE; } } for (ch = 0; ch < pDev->nSigCnt; ++ch) { pMod = &pDev->pSigCh[ch].signal; if (pMod->modified) { pDev->pSigCh[ch].sig_ch.bit.i1 = pMod->in[0].i; pDev->pSigCh[ch].sig_ch.bit.i2 = pMod->in[1].i; err = CmdWrite (pDev, pDev->pSigCh[ch].sig_ch.value, CMD_SIG_CH_LEN); pMod->modified = IFX_FALSE; } } IFXOS_MutexUnlock (pDev->memberAcc); return err; }