/**
   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;
}
Example #3
0
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);
}
Example #4
0
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;
}
Example #17
0
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;
}
Example #18
0
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;
}