⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mt88l89v2.c

📁 DTMF收发芯片88L89完美驱动(Arm,SDT251环境)
💻 C
📖 第 1 页 / 共 2 页
字号:
/* MT88L89V2.c --- MT88L89 DTMF bsp source file of PBI4A */

/* Copyright 1994-2001 Wuhan Jinglun Electronic Co., Ltd. */

/*
modification history
--------------------

*/

/* includes */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>

#include "..\inc\MT88L89V2.h"
#include "nucleus.h"
#include "irq.h"
#include "cog7312.h"
#include "routon.h"

#include "intfuimm.h"
#include "intftone.h"
#include "intfmntn.h"
#include "configio.h"
/* defines */

#define DTMF_TX_BASE		(0x200000DF)	/* DTMF send register base address */
#define DTMF_RX_BASE        (0x200000DF)	/* DTMF receive register base address */
#define DTMF_CONTROL_BASE   (0x20000020)	/* DTMF control register base address */
#define DTMF_STATUS_BASE    (0x20000020)	/* DTMF status register base address */

#define SETBIT32(var,x)		(var=var|( (unsigned long)1 << (x)))
#define DTMF_HISR_STACK_SIZE  	(1024)
#define DTMF_TX_IDLE  			(0xFF)
#define DTMF_TX_WORK  			(0x00)

#define DTMF_WRITE_STATE_IDLE			0
#define DTMF_WRITE_STATE_BUZY			-1

#define TONE_TRACE		//printf

/* globals */
unsigned char DTMF_TONE_PERD;
unsigned char DTMF_PAUSE_PERD;

unsigned char g_MastStatus;       /* status for master */
unsigned char g_MastDataRx;       /* data for rx master */
unsigned char g_MastDataTxStatus; /* tx is busy or not */
unsigned char g_MastDataTx;       /* data for Tx master */
unsigned char g_DtmfOpenStatus;   /* DTMF open status */

char g_ChannelSave = 0x0;
/* point of access register */

/* before sending DTMF, close headphone; send finished, open headphone */
extern void _HeadPhone_open(void);
extern void _HeadPhone_close(void);

//end
unsigned char * g_pStatus;
volatile /*!!!!!!Attention */ unsigned char * g_pCtrl;	/* prevent codes are optimized */
unsigned char * g_pData;

/* HISR or poll timer */

NU_TIMER	DTMF_Mast_TimerCtrl;        /* poll timer for master */
NU_TIMER    DTMF_Mast_TimerCtrlTxTone;  /* tone period control timer for master */
NU_TIMER    DTMF_Mast_TimerCtrlTxPause; /* pause period control timer for master */
NU_TIMER	DTMF_Dither_TimerCtrl;		/* Dial check disdither timer */

/* predeclartions */

unsigned char CharToDTMF(unsigned char _ch);
unsigned char DTMFToChar(unsigned char _DTMFData);
void dtmfSwitchCtrl(int _terminal, int _code);
void DTMF_Timer_Expiration(unsigned long id);
void DTMF_TxTone_Timer_Expiration(unsigned long id);
void DTMF_TxPause_Timer_Expiration(unsigned long id);
void DTMF_Dither_Timer_Expiration(unsigned long id);

/* externs */
extern int g_atthMntnFlag ;
extern void	PhDrCloseVoice(int chan_no);  /* stop RXing voice */
extern void	PhDrOpenVoice(int chan_no);   /* stop TXing voice */
extern char GetChanFromMachID(int mach_id); 

extern NU_PIPE rtn_pipe[UIMM_MAIL + 1];
#if 0
char PrintBuffer[30*1024];
void TRACE
(
	char *ps, ...	/* information to print*/
)
{
	#if 0
	char temp[256];
	va_list ap; 
   		
	//NU_Obtain_Semaphore(&ScreenSema, NU_SUSPEND);

	memset(temp, 0x0, 256);
	va_start(ap, ps);
	vsprintf(temp, ps, ap);
	va_end(ap);
	strcat(PrintBuffer, temp);
	
	//NU_Release_Semaphore(&ScreenSema);	
	#endif
}
#endif
/***************************************************
*
* DTMFSend - send DTMF message
*
* This routine send DTMF message to others module
*
* RETURNS: void
*
*/

void DTMFSend
(
	unsigned short msgcode, /* message code */
//	int orient, 	/* send direction */
	char DTMFData 	/* send data*/
)
{
	#if 1
	/* 
		LED orr, only for B295-4
		just for test...
	*/
	RtnMSG	  msg; 
	*(unsigned char *)0x80000003 ^= 0x1;
	
		
	if (msgcode == 0)	/* DTMF send finished */
	{
		msg.msg_len = 0;
		msg.msg_code = MSG_TONE_DTMFSEND_FINISH;
		NU_Send_To_Pipe( &rtn_pipe[TONE],&msg,4 + msg.msg_len,NU_NO_SUSPEND); 
	}
	else if (msgcode == 1) /* DTMF Rx data */
	{
	    msg.msg_len = 1;
	    msg.msg_data[0] = DTMFData;
	    if ( g_atthMntnFlag == 1)
	    {
	        msg.msg_code = MSG_MNTN_DTMF_DETECT_ATTH;
	        NU_Send_To_Pipe( &rtn_pipe[MNTN],&msg,4 + msg.msg_len,NU_NO_SUSPEND); 
	    }
	    else
	    {
	        msg.msg_code = MSG_UIMM_DTMF_DETECT_ATTH;
	        NU_Send_To_Pipe( &rtn_pipe[UIMM],&msg,4 + msg.msg_len,NU_NO_SUSPEND);           
	    }
	}
	else if (msgcode == 2)	/* detect dial tone */
	{
	    msg.msg_len = 0;
	    if( DTMFData == DTMF_DIAL)
			msg.msg_code = MSG_UIMM_DIALTONE_UIMM;
		else
			msg.msg_code = MSG_UIMM_DIALTONE_CLEAR_UIMM;
			
		NU_Send_To_Pipe( &rtn_pipe[UIMM],&msg,4 + msg.msg_len,NU_NO_SUSPEND);           
	}

    //printf("ATTH --- DTMFData = %c\n",DTMFData);
	#endif
}

/***************************************************
*
* DTMF_Decode_Init - DTMF initialize
*
* This routine initialize DTMF module,it will
*     1 --- register one LISR 
*     2 --- create four HISR 
*
* RETURNS: int --- 0  OK
*				   -1 Error
*
*/

int DTMF_Decode_Init(void)
{
    STATUS  status = 0;
    static  int initok = 0;
	CfgPARAM  *ptr;
	char	   param[1];
	
    if (initok == 1)
    {
    	//TONE_TRACE("BSP -- DTMF_Decode_Init has been called... \n");
    	return 0;
    }
  	
    //TONE_TRACE("BSP -- entering DTMF_Decode_Init...... \n");

	/* init status */
    g_MastDataTxStatus = DTMF_TX_IDLE;
	g_MastDataTx = DTMF_TX_IDLE;

	ptr = OneCfgParamGet (2016); //2016
	if( ptr != NULL )
	{
		memcpy(param, (char *)ptr->pVal, 4);
		DTMF_TONE_PERD = (unsigned char)(param[0]/10) + 5;
		DTMF_PAUSE_PERD = (unsigned char)(param[1]/10);
		NU_free((char *)ptr);		
	}
	if( DTMF_TONE_PERD < 4 || DTMF_TONE_PERD > 25 )
	{
		DTMF_TONE_PERD = 8;
	}
	if( DTMF_PAUSE_PERD < 4 || DTMF_PAUSE_PERD > 25 )
	{
		DTMF_PAUSE_PERD = 8;
	}
	/* create timers */
	
    status = NU_Create_Timer(&DTMF_Mast_TimerCtrl, "DTMFTMR0", DTMF_Timer_Expiration,
    						1, 2, 2, NU_DISABLE_TIMER/*NU_ENABLE_TIMER*/);
    status += NU_Create_Timer(&DTMF_Mast_TimerCtrlTxTone, "DTMFTMR2", DTMF_TxTone_Timer_Expiration,
							1, DTMF_TONE_PERD, DTMF_TONE_PERD, NU_DISABLE_TIMER);
    status += NU_Create_Timer(&DTMF_Mast_TimerCtrlTxPause, "DTMFTMR4", DTMF_TxPause_Timer_Expiration,
							1, DTMF_PAUSE_PERD, DTMF_PAUSE_PERD, NU_DISABLE_TIMER);
    status += NU_Create_Timer(&DTMF_Dither_TimerCtrl, "DTMFTMR5", DTMF_Dither_Timer_Expiration,
    						1, 4, 4, NU_DISABLE_TIMER);
    if (status != NU_SUCCESS)
    {
        //TONE_TRACE("BSP -- NU_Create_Timer error in code %d\n",status);
        return -1;
    } 
	
    g_DtmfOpenStatus = 0;	/* init open status */
    initok = 1;
    //TONE_TRACE("BSP -- successful in DTMF_Decode_Init...... \n");
	return 0;
}

/***************************************************
*
* DTMFOpen - open DTMF 
*
* This routine open DTMF device,Please call this routine before receiving or
* sending DTMF data
*
* RETURNS: int --- 0  OK
*				   <0 Error
*
*/

int DTMFOpen(void)
{
    STATUS status;
            
    /* already opened flag check */
	if (g_DtmfOpenStatus == 1)
	{
		TONE_TRACE("BSP -- DTMF has opened !!!!\n");
		return DTMF_HAS_OPENED;
	}
	
    status = NU_Control_Timer(&DTMF_Mast_TimerCtrl, NU_ENABLE_TIMER);
	//status += NU_Control_Timer(&DTMF_Dither_TimerCtrl, NU_DISABLE_TIMER);
    if (status != NU_SUCCESS)
    {
        return -1;
    }
    g_pCtrl = (volatile unsigned char *)DTMF_CONTROL_BASE;
	/* set already opened flag */
	g_DtmfOpenStatus = 1;
	
    /* DTMF initialize */
    /* See INITIALIZATION PROCEDURE, Fig15, P4-132, MT88L89 */
	*g_pCtrl = 0x00;	 
    *g_pCtrl = 0x00;	   
    *g_pCtrl = 0x08; 
    *g_pCtrl = 0x00;   

	/* See TYPICAL CONTROL SEQUENCE FOR BURST MODE APPLICATIONSM,
	   Fig15, P4-132, MT88L89 */
#define DTMF_MODE 2	   
#if DTMF_MODE == 1 /* irq mode */
    //*g_pCtrl = 0x0d;    /* disable tone out, DTMF, IRQ, Select Control Register B */
    //*g_pCtrl = 0x00;    /* burst mode */
    
#elif DTMF_MODE == 2 /* poll mode */
    *g_pCtrl = 0x08;    /* disable tone out, DTMF, no IRQ, Select Control Register B */
    *g_pCtrl = 0x01;    /* NOT burst mode: the transmit tone burst duration is determinated
                           by TOUT bit (Control Register A, b0) */
#endif
	TONE_TRACE("BSP -- DTMF open now !!!!\n");

	return 0;
}

/***************************************************
*
* DTMFClose - close DTMF device
*
* this function stop receive and send DTMF data, PLEASE call this 
* function after receiving or sending DTMF data
*
* RETURNS: int --- 0  OK
*				   <0 Error
*
*/

int DTMFClose(void)
{
   /* already opened flag check */
   
	if (g_DtmfOpenStatus == 0)
	{
		return DTMF_HAS_CLOSED;
	}
		
	g_DtmfOpenStatus = 0;	/* set already closed flag */

    NU_Control_Timer(&DTMF_Mast_TimerCtrl, NU_DISABLE_TIMER);    

	TONE_TRACE("BSP -- DTMF close now !!!!\n");

	return 0;
}

/***************************************************
*
* DTMFCheckDialOpen - check dial tone
*
* this routine first set DTMF control register, then check the special 
* bit of status register
*
* RETURNS: int --- 0  no dial tone
*				   1  a dial tone checked
*
*/
static unsigned int g_iDitherTimes = 0;
static unsigned int g_IsCheckDial = 0;
static unsigned int g_IsCheckDialOpen = 0;
int DTMFCheckDialOpen
(
	int _isDial		/* is check dial or check dial finish */
)
{
	char status;

	if ((_isDial != 0x0) && (_isDial != 0x1))
	{
		return (-1);
	}
	if (g_IsCheckDialOpen == 1) /* purpose: to avoid reopen */
	{
		return (-1);
	}
    status = NU_Control_Timer(&DTMF_Mast_TimerCtrl, NU_DISABLE_TIMER);
    if (status != NU_SUCCESS)
    {
        return (-1);
    }
	g_pCtrl = (unsigned char *)DTMF_CONTROL_BASE;	
	#if 0
	*g_pCtrl = 0x00;	/* Initialize */
	*g_pCtrl = 0x0a;	/* disable DTMF output, move ctrl to CRB*/
	*g_pCtrl = 0x00; 	/* clear CRB, no burst, no test, DTMF, bank single tone */  
	*g_pCtrl = 0x07;    /* enable tone out, CP, IRQ */
	#endif

	 
	 #if 1
	*g_pCtrl = 0x00;	/* Initialize */
	*g_pCtrl = 0x0e;	/* disable DTMF output, move ctrl to CRB*/
	*g_pCtrl = 0x00; 	/* clear CRB, no burst, no test, DTMF, bank single tone */  
	*g_pCtrl = 0x05;    /* enable tone out, CP, IRQ */
	#endif
	
	g_iDitherTimes = 0;
	g_IsCheckDial = _isDial;
	g_DtmfOpenStatus = 0;
	//NU_Sleep(50);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -