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

📄 madevdrv.c

📁 是一个手机功能的模拟程序
💻 C
📖 第 1 页 / 共 5 页
字号:
/****************************************************************************
 *
 *		Copyright 2002-2003	YAMAHA CORPORATION. All rights reserved.
 *
 *		Module		: madevdrv.c
 *
 *		Description	: MA-5 Device Driver
 *
 *
 *		Version		: 2.1.7 	2003.6.23
 *
 *
 ****************************************************************************/
#include "madevdrv.h"

#define MADEVDRV_WAIT_TIMEOUT			(10000)  /* ms */
#define	ENABLE_IRQ						0
#define	DISABLE_IRQ						1

#define	MADEVDRV_STREAM_STATE_IDLE		0
#define	MADEVDRV_STREAM_STATE_STANDBY	1
#define	MADEVDRV_STREAM_STATE_PLAYING	2
#define	MADEVDRV_STREAM_STATE_ENDOFDATA	3

#define	MADEVDRV_ACTIVE_DELAYEDSEQ		1
#define	MADEVDRV_ACTIVE_PHRASESEQ		2
#define	MADEVDRV_ACTIVE_HVSEQ			4


/* Struct Definitions */

typedef struct _MA_SBUF_INFO
{
	UINT32	dWriteNum;
	UINT32	dReadNum;
	UINT32	dBufTotal;
	UINT32	dBufPtr;
	UINT32	dBufSize[MA_SBUF_NUM];
} MA_SBUF_INFO;

typedef struct _MA_STREAM_AUDIO_INFO
{
	UINT8	bState;
	UINT8	bCh;
	UINT32	dFormat;
	UINT8 *	pbWaveData;
	UINT32	dWaveSize;
	UINT32	dEndPoint;
	UINT32	dPrvPoint;
} MA_STREAM_AUDIO_INFO, *PMA_STREAM_AUDIO_INFO;

typedef struct _MADEVDRVINFO
{
	MA_SBUF_INFO	SbufInfo;
	MA_STREAM_AUDIO_INFO	StreamInfo[MA_MAX_STREAM_AUDIO];

	UINT8	bSbufBuffer[MA_SBUF_NUM][MA_FIFO_SIZE];
	void (* pIntFunc[12])(UINT32 dCtrl);

	UINT8	bStatusReg;
	UINT8	bIrqProc;
	UINT8	bMaskInterrupt;
	UINT8	bSlave;
	UINT32	dSeqId;
	UINT32	dEndofSequence;
	UINT32	dActiveSequencer;
	UINT32	dPendingIrq;
	UINT32	dStreamEoInfo;
} MADEVDRVINFO, *PMADEVDRVINFO;


MADEVDRVINFO gMaDevDrvInfo;
static PMADEVDRVINFO pgMaDevDrvInfo = &gMaDevDrvInfo;

extern void 	machdep_ErrHandler				( SINT32 sdError );
extern void 	machdep_Wait					( UINT32 dWaitTime );
extern void	machdep_Sleep					( UINT32 dSleepTime );
extern SINT32	machdep_WaitValidData			( UINT8 bFlag );
extern void 	machdep_WriteStatusFlagReg		( UINT8 bData );
extern UINT8	machdep_ReadStatusFlagReg		( void );
extern void	machdep_WriteDataReg			( UINT8 bData );
extern void	machdep_WriteDataRegN			( UINT8* pbData, UINT32 dSize );
extern void	machdep_WriteDataRegValN		( UINT8 bVal, UINT32 dSize );
extern UINT8	machdep_ReadDataReg				( void );
extern SINT32	machdep_CheckDelayedFifoEmpty	( void );
extern SINT32	machdep_WaitDelayedFifoEmpty 	( void );
extern SINT32	machdep_WaitImmediateFifoEmpty	( void );
extern void 	machdep_GenerateIrqProcTask		( UINT32 dIrqFlag, UINT8 bOldSetting );
extern SINT32	machdep_PowerManagement			( UINT8 bMode );
extern SINT32	machdep_WaitSequencerStop		( void );

extern UINT32	gdPrevAccessType;

static void		dummy_IntFunc( UINT32 dCtrl );
static SINT32	StreamSetup( UINT32 dSaId );
static SINT32	StreamUpdate( UINT32 dSaId );
static SINT32	ControlInterrupt( UINT32 dIrqCtrlReg, UINT32 dCtrl, UINT8 bIntCtrl );
static void		SoftInt0( UINT32 dCtrl );
static void		SoftInt1( UINT32 dCtrl );
static void		SoftInt2( UINT32 dCtrl );
static void		SoftInt3( UINT32 dCtrl );
static void		SoftInt4( UINT32 dCtrl );
static void		StreamPg0( UINT32 dCtrl );
static void		StreamPg1( UINT32 dCtrl );
static void		Timer2( UINT32 dCtrl );
static void		InitRegisters( void );
static UINT8	WriteStatusFlagReg( UINT8 bReg );
static SINT32	WriteStereoAdpcmZeroVal( UINT32 dAddress, UINT32 dSize );

#include "masnddrv.h"
#include "masndseq.h"
#include "maresmgr.h"

#ifdef COLORLED_SUPPORT
#define MADEVDRV_LED_PATTERN_NUM 8
static const UINT8 abLedPattern[MADEVDRV_LED_PATTERN_NUM] =
					{ 1, 2, 3, 4, 5, 6, 7, 0 };
static UINT32 dwLedCount = 0;
#endif

/****************************************************************************
	 dummy Description
 ****************************************************************************/
static void dummy_IntFunc( UINT32 dCtrl )
{
	(void)dCtrl;						/* for unused warning message */

	MADEVDRV_DBGMSG((" dummy_IntFunc: bCtrl=%d\n", dCtrl));
}
/****************************************************************************
 *	MaDevDrv_Initialize
 *
 *	Description:
 *			Initialize the MA Device Driver module.
 *	Arguments:
 *			None
 *	Return:
 *			0		success
 *			-1		error
 *
 ****************************************************************************/
SINT32 MaDevDrv_Initialize( void )
{
	UINT32	i;							/* loop counter */

	MADEVDRV_DBGMSG(("MaDevDrv_Initialize\n"));

	pgMaDevDrvInfo->SbufInfo.dWriteNum = 0;
	pgMaDevDrvInfo->SbufInfo.dReadNum  = 0;
	pgMaDevDrvInfo->SbufInfo.dBufTotal = 0;
	pgMaDevDrvInfo->SbufInfo.dBufPtr   = 0;

	for ( i = 0; i < MA_SBUF_NUM; i++ )
	{
		pgMaDevDrvInfo->SbufInfo.dBufSize[i] = 0;
	}

	/* Initialize for Stream Audio */
	for ( i = 0; i < MA_MAX_STREAM_AUDIO; i++ )
	{
		pgMaDevDrvInfo->StreamInfo[i].bState 		= MADEVDRV_STREAM_STATE_IDLE;
		pgMaDevDrvInfo->StreamInfo[i].bCh			= 0;
		pgMaDevDrvInfo->StreamInfo[i].dFormat		= 0;
		pgMaDevDrvInfo->StreamInfo[i].pbWaveData	= NULL;
		pgMaDevDrvInfo->StreamInfo[i].dWaveSize	= 0;
		pgMaDevDrvInfo->StreamInfo[i].dEndPoint 		= 0;
		pgMaDevDrvInfo->StreamInfo[i].dPrvPoint		= 0;
	}

	pgMaDevDrvInfo->bStatusReg		= 0x80;
	pgMaDevDrvInfo->bIrqProc		= 0;
	pgMaDevDrvInfo->bMaskInterrupt	= 0;
	pgMaDevDrvInfo->bSlave			= 0xff;
	pgMaDevDrvInfo->dSeqId			= 0;
	pgMaDevDrvInfo->dEndofSequence	= 0;
	pgMaDevDrvInfo->dActiveSequencer= 0;
	pgMaDevDrvInfo->dPendingIrq		= 0;
	pgMaDevDrvInfo->dStreamEoInfo	= 0;

	/* register IRQ functions */
	pgMaDevDrvInfo->pIntFunc[0]  = StreamPg0;			/* StreamPG #0 */
	pgMaDevDrvInfo->pIntFunc[1]  = StreamPg1;			/* StreamPG #1 */
	pgMaDevDrvInfo->pIntFunc[2]  = SoftInt0;			/* Soft Int #0 */
	pgMaDevDrvInfo->pIntFunc[3]  = SoftInt1;			/* Soft Int #1 */
	pgMaDevDrvInfo->pIntFunc[4]  = dummy_IntFunc;		/* Timer #0(not used) */
	pgMaDevDrvInfo->pIntFunc[5]  = dummy_IntFunc;		/* Timer #1(not used) */
	pgMaDevDrvInfo->pIntFunc[6]  = Timer2;				/* Timer #2 */
	pgMaDevDrvInfo->pIntFunc[7]  = MaDevDrv_Fifo;		/* FIFO */
	pgMaDevDrvInfo->pIntFunc[8]  = SoftInt2;			/* Soft Int #2 */
	pgMaDevDrvInfo->pIntFunc[9]  = SoftInt3;			/* Soft Int #3 */
	pgMaDevDrvInfo->pIntFunc[10] = SoftInt4;			/* Soft Int #4 */
	pgMaDevDrvInfo->pIntFunc[11] = dummy_IntFunc;		/* Soft Int #5 */
	
	/* Initialize register access flag */
	gdPrevAccessType = MADEVDRV_ACCESS_WRITE;

	return MASMW_SUCCESS;
}
/****************************************************************************
 *	MaDevDrv_Terminate
 *
 *	Description:
 *			Terminate the MA Device Driver module.
 *	Arguments:
 *			None
 *	Return:
 *			0		success
 *			-1		error
 *
 ****************************************************************************/
SINT32 MaDevDrv_Terminate( void )
{
	MADEVDRV_DBGMSG(("MaDevDrv_Terminate\n"));

	return MASMW_SUCCESS;
}
/****************************************************************************
 *	MaDevDrv_HardwareInitialize
 *
 *	Description:
 *			Initialize hardware.
 *	Arguments:
 *			None
 *	Return:
 *			0		success
 *			-1		error
 *
 ****************************************************************************/
SINT32 MaDevDrv_HardwareInitialize( void )
{
	SINT32	sdResult;					/* result of function */

	MADEVDRV_DBGMSG(("MaDevDrv_HardwareInitialize\n"));

	gdPrevAccessType = MADEVDRV_ACCESS_WRITE;

	/* Initialize the uninitialized registers by software reset */
	InitRegisters();

	/* Set the PLL. */
	MaDevDrv_WriteIntermediateReg( MAI_PLL_SETTING_1, MA_ADJUST1_VALUE );
	MaDevDrv_WriteIntermediateReg( MAI_PLL_SETTING_2, MA_ADJUST2_VALUE );

	/* Disable power down mode. */
	sdResult = machdep_PowerManagement( 0 );

	/* error  */
	if ( sdResult != MASMW_SUCCESS )
	{
		return sdResult;
	}

	MaDevDrv_WriteIntermediateReg( MAI_IRQ_CONTROL_1, 
					MAB_IRQCTRL_ETM2 | MAB_IRQCTRL_ESIRQ1 | MAB_IRQCTRL_ESIRQ0  );

	MaDevDrv_WriteIntermediateReg( MAI_IRQ_CONTROL_2, MAB_IRQCTRL_ESIRQ4 | MAB_IRQCTRL_ESIRQ3 | MAB_IRQCTRL_ESIRQ2  );

	/* set stream buffer size and irq point */
	/* buff_size=1024, irq_point=1/4 */
	MaDevDrv_WriteIntermediateReg( MAI_STM_IRQ_CTRL, 0x10 );

	return MASMW_SUCCESS;
}
/****************************************************************************
 *	MaDevDrv_PowerManagement
 *
 *	Description:
 *			Power management.
 *	Argument:
 *			bMode	0: Hardware initialize sequence (normal)
 *					1: Power down change sequence
 *					2: Power down release sequence
 *	Return:
 *			0		success
 *			< 0		error code
 *
 ****************************************************************************/
SINT32 MaDevDrv_PowerManagement( UINT8 bMode )
{
	SINT32	sdResult;					/* sdResult of function */

	MADEVDRV_DBGMSG(("MaDevDrv_PowerManagement: bMode=%d\n", bMode));

	sdResult = machdep_PowerManagement( bMode );
	return sdResult;
}
/****************************************************************************
 *	MaDevDrv_WriteIntermediateReg
 *
 *	Description:
 *			Write data to intermediate register.
 *	Arguments:
 *			dNumber	Register Index
 *			bData	Write Data
 *	Return:
 *			0		success
 *			< 0		error code
 *
 ****************************************************************************/
SINT32 MaDevDrv_WriteIntermediateReg( UINT32 dNumber, UINT8 bData )
{
	/* increment Irq access counter */
	pgMaDevDrvInfo->bMaskInterrupt++;

	/* set specified reg# */
	WriteStatusFlagReg( (UINT8)(dNumber & 0x7F) );

	/* write data */
	machdep_WriteDataReg( bData );

	/* enable interrupt if needed */
	if ( (--pgMaDevDrvInfo->bMaskInterrupt)==0 )
	{
		WriteStatusFlagReg( MAB_IRQ_ENABLE );
	}

	return MASMW_SUCCESS;
}
/****************************************************************************
 *	MaDevDrv_ReadIntermediateReg
 *
 *	Description:
 *			Read data from intermediate register
 *	Arguments:
 *			dNumber	Register Index
 *	Return:
 *			read data
 *
 ****************************************************************************/
UINT8 MaDevDrv_ReadIntermediateReg( UINT32 dNumber )
{
	UINT8 bData;

	/* increment Irq access counter */
	pgMaDevDrvInfo->bMaskInterrupt++;

	/* set specified reg# */
	WriteStatusFlagReg( (UINT8)(dNumber & 0x7F) );

	/* read data */
	bData = machdep_ReadDataReg();

	/* enable interrupt if needed */
	if ( (--pgMaDevDrvInfo->bMaskInterrupt)==0 )
	{
		WriteStatusFlagReg( MAB_IRQ_ENABLE );
	}

	return bData;
}
/****************************************************************************
 *	MaDevDrv_ReceiveData
 *
 *	Description:
 *			Read byte data of register or memory.
 *	Argument:
 *			dAddress	address of the register or memory for read
 *	Return:
 *			read data
 *
 ****************************************************************************/
SINT32 MaDevDrv_ReceiveData( UINT32	dAddress )
{
	UINT8	bRdData;
	SINT32	sdResult;

	MADEVDRV_DBGMSG(("    MaDevDrv_ReceiveData: adrs=%ld\n", dAddress));

	/* increment Irq access counter */
	pgMaDevDrvInfo->bMaskInterrupt++;

	/* set REG_ID #3   */
	WriteStatusFlagReg( MAI_IMMEDIATE_READ );

	/* check status */
	sdResult = machdep_WaitImmediateFifoEmpty();

	/* error  */
	if ( sdResult < MASMW_SUCCESS )
	{
		/* enable interrupt if needed */
		MaDevDrv_EnableIrq();
		return sdResult;
	}

	/* write direct packet for read */
	if		( dAddress < 0x0080 )
	{
		machdep_WriteDataReg( (UINT8)((dAddress >>  0 ) | 0x80) );
	}
	else if ( dAddress < 0x4000 )
	{
		machdep_WriteDataReg( (UINT8)((dAddress >>  0 ) & 0x7F) );
		machdep_WriteDataReg( (UINT8)((dAddress >>  7 ) | 0x80) );
	}
	else
	{
		machdep_WriteDataReg( (UINT8)((dAddress >>  0 ) & 0x7F) );
		machdep_WriteDataReg( (UINT8)((dAddress >>  7 ) & 0x7F) );
		machdep_WriteDataReg( (UINT8)((dAddress >> 14 ) | 0x80) );
	}

	/* Read Buffer # */
	machdep_WriteDataReg( (UINT8)0x80 );

	/* check status */
	sdResult = machdep_WaitValidData( MAB_STAT_VALID_R );

	/* error  */
	if ( sdResult < MASMW_SUCCESS )
	{
		/* enable interrupt if needed */
		MaDevDrv_EnableIrq();
		return sdResult;
	}

	/* clear VALID_R bit and set REG_ID #1   */
	WriteStatusFlagReg( MAB_STAT_VALID_R|MAI_READ_BUF );

	/* read data */
	bRdData = machdep_ReadDataReg();

	/* enable interrupt if needed */
	if ( (--pgMaDevDrvInfo->bMaskInterrupt)==0 )
	{
		WriteStatusFlagReg( MAB_IRQ_ENABLE );
	}

	return ((SINT32)bRdData&0x000000FF);
}
/****************************************************************************
 *	MaDevDrv_SendDirectPacket
 *
 *	Description:
 *			Write direct packets to the REG_ID #2 direct write register.
 *	Argument:
 *			pbData	pointer to the direct packets
 *			dSize	size of the direct packets
 *	Return:
 *			0		success
 *			< 0		error code
 *
 ****************************************************************************/
SINT32 MaDevDrv_SendDirectPacket( const UINT8 * pbData, UINT32 dSize )
{
	UINT32	i, j;
	SINT32	sdResult;

	MADEVDRV_DBGMSG(("    MaDevDrv_SendDirectPacket: pt=%p, sz=%d\n", pbData, dSize));

	if( dSize == 0 )  return MASMW_SUCCESS;

	/* increment Irq access counter */
	pgMaDevDrvInfo->bMaskInterrupt++;

	/* set REG_ID #2   */
	WriteStatusFlagReg( MAI_IMMEDIATE_WRITE );

	/* write data */
	i = dSize/64;

	while ( i-- != 0 )
	{
		/* check status */
		sdResult = machdep_WaitImmediateFifoEmpty();

		/* error  */
		if ( sdResult < MASMW_SUCCESS )
		{
			/* enable interrupt if needed */
			MaDevDrv_EnableIrq();
			return sdResult;
		}

		/* write 64 bytes */
		machdep_WriteDataRegN( (UINT8*)pbData, (UINT32)64 );
		pbData += 64;
	}

	/* write odd data */
	if ( (j=(dSize%64)) != 0 )
	{
		/* check status */
		sdResult = machdep_WaitImmediateFifoEmpty();

		/* error  */
		if ( sdResult < MASMW_SUCCESS )
		{
			/* enable interrupt if needed */
			MaDevDrv_EnableIrq();
			return sdResult;
		}

		/* write data */
		machdep_WriteDataRegN( (UINT8*)pbData, j );
	}

	/* enable interrupt if needed */
	if ( (--pgMaDevDrvInfo->bMaskInterrupt)==0 )
	{
		WriteStatusFlagReg( MAB_IRQ_ENABLE );
	}

	return MASMW_SUCCESS;

⌨️ 快捷键说明

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