📄 madevdrv.c
字号:
/****************************************************************************
*
* 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 + -