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

📄 hssi_isr.c

📁 WinCE5.0BSP for Renesas SH7770
💻 C
字号:
//
//  Copyright(C) Renesas Technology Corp. 2003-2005. All rights reserved.
//
//  NK Kernel for ITS-DS7 Ver.1.0.0
//
//  FILE      : hssi_isr.c
//  CREATED   : 2003.03.12
//  MODIFIED  : 2005.02.24
//  AUTHOR    : Renesas Technology Corp.
//  HARDWARE  : RENESAS ITS-DS7
//  HISTORY   : 
//              2003.06.20
//              - Created release code.
//                (based on RENESAS ITS-DS6 Source Kit Ver.2.2.0 for WCE4.2)
//              2004.09.01
//              - Created release code for WCE5.0.
//              2005.02.24
//              - Added error processing in overflow and underflow.

#include <windows.h>
#include <platform.h>
#include <sh7770.h>
#include <oalintr.h>
#include <drv_glob.h>
#include <dma.h>

#define Read(reg)		(*(volatile unsigned long * const)(reg))
#define Write(reg, val)	(*(volatile unsigned long * const)(reg)) = (val)

#define CLRBIT(reg, val) Write((reg), (Read(reg) & (~val)))
#define SETBIT(reg, val) Write((reg), (Read(reg) | val))


int	hssi_isr0(void);
int	hssi_isr1(void);
int	hssi_isr2(void);
int	hssi_isr3(void);
int	hssi_isr4(void);

#define SSI_CR		0x00000000
#define SSI_SR		0x00000004
#define SSI_CRMASK	0xe0fffffe
#define SSI_SRMASK	0xf3ffffff

// HSSI Control Register (CR)
#define HSSI_CR_DMEN			0x10000000		// DMA Enable(28)
#define HSSI_CR_UIEN			0x08000000		// Underflow IRQ Enable(27)
#define HSSI_CR_OIEN			0x04000000		// Overflow IRQ Enable(26)
#define HSSI_CR_EN				0x00000001		// HSSI Module Enable(0)

#define SSI0_INT	0x00000040
#define SSI1_INT	0x00000080
#define SSI2_INT	0x00000100

#define SR_DMRQ		0x10000000
#define SR_UIRQ		0x08000000
#define SR_OIRQ		0x04000000
#define SR_IIRQ		0x02000000
#define SR_DIRQ		0x01000000

#pragma optimize("", off)
void restart_hssi(ULONG pRegBase, int ch, ULONG clear_SR)
{
	ULONG	RegValue;

	//SSI disable(EN:0,DMEN:0,UIEN:0,OIEN:0)
	WRITE_REGISTER_ULONG(pRegBase + SSI_CR,
		READ_REGISTER_ULONG(pRegBase + SSI_CR) & ~(HSSI_CR_DMEN | HSSI_CR_EN | HSSI_CR_UIEN | HSSI_CR_OIEN));

	// wait idle from SSI
	do{
		RegValue = READ_REGISTER_ULONG(pRegBase + SSI_SR);
	}while((RegValue & SR_IIRQ) != SR_IIRQ);

	//stop DMA
	WRITE_REGISTER_ULONG(SH7770_DMAC_REGBASE + DMAC_DINTMR_OFFSET,
			READ_REGISTER_ULONG(SH7770_DMAC_REGBASE + DMAC_DINTMR_OFFSET) & ~(0x00000001 << ch));
	WRITE_REGISTER_ULONG(SH7770_DMAC_REGBASE + DMAC_DSTPR_OFFSET + (0x40 * ch), 1);
	READ_REGISTER_ULONG(SH7770_DMAC_REGBASE + DMAC_DINTMR_OFFSET);		// Coherency measures

	//clear SR(overflow/underflow)
	WRITE_REGISTER_ULONG(pRegBase + SSI_SR,
		READ_REGISTER_ULONG(pRegBase + SSI_SR) & ~(clear_SR));

	//start DMA
	WRITE_REGISTER_ULONG(SH7770_DMAC_REGBASE + DMAC_DCMDR_OFFSET + (0x40 * ch), DCMDR_DMEN);
	WRITE_REGISTER_ULONG(SH7770_DMAC_REGBASE + DMAC_DINTMR_OFFSET,
		READ_REGISTER_ULONG(SH7770_DMAC_REGBASE + DMAC_DINTMR_OFFSET) | (0x00000001 << ch));
	READ_REGISTER_ULONG(SH7770_DMAC_REGBASE + DMAC_DINTMR_OFFSET);		// Coherency measures

	//SSI enable(EN:1,DMEN:1,UIEN:1,OIEN:1)
	WRITE_REGISTER_ULONG(pRegBase + SSI_CR,
		READ_REGISTER_ULONG(pRegBase + SSI_CR) | (HSSI_CR_DMEN | HSSI_CR_EN | HSSI_CR_UIEN | HSSI_CR_OIEN));
}

int	hssi_isr0(void)
{
	ULONG ssi_sr;
#ifdef	DEBUG
	char string[8];
	static	int		ii = 0;
		// Output to LED (HSSI Playing)
		string[0] = 'H';
		string[1] = 'S';
		string[2] = 'S';
		string[3] = 'I';
		string[4] = '0' + (UCHAR)ii / 100;
		string[5] = '0' + (UCHAR)(ii %100) / 10;
		string[6] = '0' + (UCHAR)(ii % 10);
		string[7] = '\0';
		PrintLED(string);
		if( ++ii > 1000 )	ii = 0;
#endif
	//SSI0 check overflow/underflow
	ssi_sr = READ_REGISTER_ULONG(SSI0_REGBASE + SSI_SR) & (SR_OIRQ|SR_UIRQ);
    if(ssi_sr != 0x00000000){
		restart_hssi(SSI0_REGBASE, DPTR_DDPT_HSSI0, ssi_sr);
	}

	//SSI1 check overflow/underflow
	ssi_sr = READ_REGISTER_ULONG(SSI1_REGBASE + SSI_SR) & (SR_OIRQ|SR_UIRQ);
    if(ssi_sr != 0x00000000){
		restart_hssi(SSI1_REGBASE, DPTR_SDPT_HSSI1, ssi_sr);
	}

	//SSI2 check overflow/underflow
	ssi_sr = READ_REGISTER_ULONG(SSI2_REGBASE + SSI_SR) & (SR_OIRQ|SR_UIRQ);
    if(ssi_sr != 0x00000000){
		restart_hssi(SSI2_REGBASE, DPTR_DDPT_HSSI2, ssi_sr);
	}

	//SSI3 check overflow/underflow
	ssi_sr = READ_REGISTER_ULONG(SSI3_REGBASE + SSI_SR) & (SR_OIRQ|SR_UIRQ);
    if(ssi_sr != 0x00000000){
		restart_hssi(SSI3_REGBASE, DPTR_SDPT_HSSI3, ssi_sr);
	}

    return SYSINTR_NOP;
}

int	hssi_isr1(void)
{
    int		index, ch;
#ifdef	DEBUG
    char string[8];
    static	int		ii = 0;

		// Output to LED (HSSI Playing)
		string[0] = 'S';
		string[1] = 'S';
		string[2] = 'I';
		string[3] = '1';
		string[4] = 'P';
		string[5] = '0' + (UCHAR)(ii %100) / 10;
		string[6] = '0' + (UCHAR)(ii % 10);
		string[7] = '\0';
		PrintLED(string);
		if( ++ii > 100 )	ii = 0;
#endif

	// Get Index & ch
    index = READ_REGISTER_ULONG(DRV_GLOBAL_BASE + AUD_INDEX_HSSI1_OFFSET);
    ch    = READ_REGISTER_ULONG(DRV_GLOBAL_BASE + (sizeof(AUDIO_GLOBALS) * index) + PLAY_CH_OFFSET);

    // DMA Transmitted Interrupts Disable
	WRITE_REGISTER_ULONG(SH7770_DMAC_REGBASE + DMAC_DINTMR_OFFSET,
		READ_REGISTER_ULONG(SH7770_DMAC_REGBASE + DMAC_DINTMR_OFFSET) & ~((ULONG)1 << ch));
	READ_REGISTER_ULONG(SH7770_DMAC_REGBASE + DMAC_DINTMR_OFFSET);		// Coherency measures

    // DMA Transmitted Interrupts flag Clear
    WRITE_REGISTER_ULONG(SH7770_DMAC_REGBASE + DMAC_DINTCR_OFFSET, (ULONG)1 << ch);

    // set Playback-interrupts flag (=1)
    WRITE_REGISTER_ULONG(DRV_GLOBAL_BASE + (sizeof(AUDIO_GLOBALS) * index) + OUTINT_OFFSET, (ULONG)1);

    // set Record-interrupts flag (=0)
//    WRITE_REGISTER_ULONG(DRV_GLOBAL_BASE + (sizeof(AUDIO_GLOBALS) * index) + ININT_OFFSET, (ULONG)0);

    // Audio Playback Address != NULL ?
    if( READ_REGISTER_ULONG(DRV_GLOBAL_BASE + (sizeof(AUDIO_GLOBALS) * index) + PLAY_ADDRESS_OFFSET) != (ULONG)NULL ){

		// DMA Interrupt flag (for OEMInterruptEnable, OEMInterruptDone)
		 WRITE_REGISTER_UCHAR(DRV_GLOBAL_BASE + DMA_INTERRUPT_FLG_OFFSET + ch, (ULONG)1);

		//
		// Playback
		//
		return SYSINTR_HSSI1;
    }
    else{
        //
        // Stop (Playback data empty)
        //

        // HSSI1 TxDMA Disable
//		WRITE_REGISTER_ULONG(SSI0_REGBASE + SSI_CR,
//			READ_REGISTER_ULONG(SSI0_REGBASE + SSI_CR) & SSI_CRMASK );

        return SYSINTR_HSSI1;
    }
//    return SYSINTR_HSSI;
}

int	hssi_isr2(void)
{
    int		index, ch;
#ifdef	DEBUG
    char string[8];
    static	int		ii = 0;

		// Output to LED (HSSI Recording)
		string[0] = 'S';
		string[1] = 'S';
		string[2] = 'I';
		string[3] = '1';
		string[4] = 'R';
		string[5] = '0' + (UCHAR)(ii %100) / 10;
		string[6] = '0' + (UCHAR)(ii % 10);
		string[7] = '\0';
		PrintLED(string);
		if( ++ii > 100 )	ii = 0;
#endif

	// Get Index & ch
    index = READ_REGISTER_ULONG(DRV_GLOBAL_BASE + AUD_INDEX_HSSI1_OFFSET);
    ch    = READ_REGISTER_ULONG(DRV_GLOBAL_BASE + (sizeof(AUDIO_GLOBALS) * index) + REC_CH_OFFSET);

    // DMA Transmitted Interrupts Disable (DINTMR)
	WRITE_REGISTER_ULONG(SH7770_DMAC_REGBASE + DMAC_DINTMR_OFFSET,
				READ_REGISTER_ULONG(SH7770_DMAC_REGBASE + DMAC_DINTMR_OFFSET) & ~((ULONG)1 << ch));

    // DMA Transmitted End flag clear (DINTCR)
    WRITE_REGISTER_ULONG(SH7770_DMAC_REGBASE + DMAC_DINTCR_OFFSET, (ULONG)1 << ch);
	READ_REGISTER_ULONG(SH7770_DMAC_REGBASE + DMAC_DINTMR_OFFSET);		// Coherency measures

    // End of Recording ?
    if( READ_REGISTER_ULONG(DRV_GLOBAL_BASE + (sizeof(AUDIO_GLOBALS) * index) + REC_ADDRESS_OFFSET) == (ULONG)NULL ){

        // HSSI1 RxDMA Disable
		WRITE_REGISTER_ULONG(SSI1_REGBASE + SSI_CR,
			READ_REGISTER_ULONG(SSI1_REGBASE + SSI_CR) & SSI_CRMASK );

		return SYSINTR_HSSI1;
    }

    // set Record-interrupts flag (=1)
    WRITE_REGISTER_ULONG(DRV_GLOBAL_BASE + (sizeof(AUDIO_GLOBALS) * index) + ININT_OFFSET, (ULONG)1);

    // set Playback-interrupts flag (=0)
//    WRITE_REGISTER_ULONG(DRV_GLOBAL_BASE + (sizeof(AUDIO_GLOBALS) * index) + OUTINT_OFFSET, (ULONG)0);

    // DMA Interrupt flag (for OEMInterruptEnable, OEMInterruptDone)
    WRITE_REGISTER_UCHAR(DRV_GLOBAL_BASE + DMA_INTERRUPT_FLG_OFFSET + ch, (ULONG)1);

    return SYSINTR_HSSI1;
}

int	hssi_isr3(void)
{
    int		index, ch;
#ifdef	DEBUG
    char string[8];
    static	int		ii = 0;

	// Output to LED (HSSI Playing)
		string[0] = 'S';
		string[1] = 'S';
		string[2] = 'I';
		string[3] = '2';
		string[4] = 'P';
		string[5] = '0' + (UCHAR)(ii %100) / 10;
		string[6] = '0' + (UCHAR)(ii % 10);
		string[7] = '\0';
		PrintLED(string);
		if( ++ii > 100 )	ii = 0;
#endif

	// Get Index & ch
    index = READ_REGISTER_ULONG(DRV_GLOBAL_BASE + AUD_INDEX_HSSI2_OFFSET);
    ch    = READ_REGISTER_ULONG(DRV_GLOBAL_BASE + (sizeof(AUDIO_GLOBALS) * index) + PLAY_CH_OFFSET);

	// dummy playback for hssi4(hssi4 is need hssi3's clock)
    if( READ_REGISTER_ULONG(DRV_GLOBAL_BASE + (sizeof(AUDIO_GLOBALS) * index) + REC_ADDRESS_OFFSET) != (ULONG)NULL ){
	    if( READ_REGISTER_ULONG(DRV_GLOBAL_BASE + (sizeof(AUDIO_GLOBALS) * index) + PLAY_ADDRESS_OFFSET) == (ULONG)NULL ){
		    // DMA Transmitted Interrupts flag Clear
		    WRITE_REGISTER_ULONG(SH7770_DMAC_REGBASE + DMAC_DINTCR_OFFSET, (ULONG)1 << ch);
			READ_REGISTER_ULONG(SH7770_DMAC_REGBASE + DMAC_DINTMR_OFFSET);		// Coherency measures

	        return SYSINTR_NOP;
		}
	}

    // DMA Transmitted Interrupts Disable
	WRITE_REGISTER_ULONG(SH7770_DMAC_REGBASE + DMAC_DINTMR_OFFSET,
		READ_REGISTER_ULONG(SH7770_DMAC_REGBASE + DMAC_DINTMR_OFFSET) & ~((ULONG)1 << ch));

    // DMA Transmitted Interrupts flag Clear
    WRITE_REGISTER_ULONG(SH7770_DMAC_REGBASE + DMAC_DINTCR_OFFSET, (ULONG)1 << ch);
	READ_REGISTER_ULONG(SH7770_DMAC_REGBASE + DMAC_DINTMR_OFFSET);		// Coherency measures

    // set Playback-interrupts flag (=1)
    WRITE_REGISTER_ULONG(DRV_GLOBAL_BASE + (sizeof(AUDIO_GLOBALS) * index) + OUTINT_OFFSET, (ULONG)1);

    // set Record-interrupts flag (=0)
//    WRITE_REGISTER_ULONG(DRV_GLOBAL_BASE + (sizeof(AUDIO_GLOBALS) * index) + ININT_OFFSET, (ULONG)0);

    // Audio Playback Address != NULL ?
    if( READ_REGISTER_ULONG(DRV_GLOBAL_BASE + (sizeof(AUDIO_GLOBALS) * index) + PLAY_ADDRESS_OFFSET) != (ULONG)NULL ){

		// DMA Interrupt flag (for OEMInterruptEnable, OEMInterruptDone)
		 WRITE_REGISTER_UCHAR(DRV_GLOBAL_BASE + DMA_INTERRUPT_FLG_OFFSET + ch, (ULONG)1);

		//
		// Playback
		//
		return SYSINTR_HSSI2;
    }
    else{
        //
        // Stop (Playback data empty)
        //

        // HSSI2 TxDMA Disable
//		WRITE_REGISTER_ULONG(SSI2_REGBASE + SSI_CR,
//			READ_REGISTER_ULONG(SSI2_REGBASE + SSI_CR) & SSI_CRMASK );

        return SYSINTR_HSSI2;
    }
//    return SYSINTR_HSSI;
}

int	hssi_isr4(void)
{
    int		index, ch, pch;
#ifdef	DEBUG
    char string[8];
    static	int		ii = 0;

		// Output to LED (HSSI Recording)
		string[0] = 'S';
		string[1] = 'S';
		string[2] = 'I';
		string[3] = '2';
		string[4] = 'R';
		string[5] = '0' + (UCHAR)(ii %100) / 10;
		string[6] = '0' + (UCHAR)(ii % 10);
		string[7] = '\0';
		PrintLED(string);
		if( ++ii > 100 )	ii = 0;
#endif

	// Get Index & ch
    index = READ_REGISTER_ULONG(DRV_GLOBAL_BASE + AUD_INDEX_HSSI2_OFFSET);
    ch    = READ_REGISTER_ULONG(DRV_GLOBAL_BASE + (sizeof(AUDIO_GLOBALS) * index) + REC_CH_OFFSET);
    pch    = READ_REGISTER_ULONG(DRV_GLOBAL_BASE + (sizeof(AUDIO_GLOBALS) * index) + PLAY_CH_OFFSET);

    // DMA Transmitted Interrupts Disable (DINTMR)
	WRITE_REGISTER_ULONG(SH7770_DMAC_REGBASE + DMAC_DINTMR_OFFSET,
				READ_REGISTER_ULONG(SH7770_DMAC_REGBASE + DMAC_DINTMR_OFFSET) & ~((ULONG)1 << ch));

    // DMA Transmitted End flag clear (DINTCR)
    WRITE_REGISTER_ULONG(SH7770_DMAC_REGBASE + DMAC_DINTCR_OFFSET, (ULONG)1 << ch);
	READ_REGISTER_ULONG(SH7770_DMAC_REGBASE + DMAC_DINTMR_OFFSET);		// Coherency measures

    // End of Recording ?
    if( READ_REGISTER_ULONG(DRV_GLOBAL_BASE + (sizeof(AUDIO_GLOBALS) * index) + REC_ADDRESS_OFFSET) == (ULONG)NULL ){

        // HSSI2 RxDMA Disable
		WRITE_REGISTER_ULONG(SSI3_REGBASE + SSI_CR,
			READ_REGISTER_ULONG(SSI3_REGBASE + SSI_CR) & SSI_CRMASK );

		// stop dummy playback for hssi4(hssi4 is need hssi3's clock)
	    if( READ_REGISTER_ULONG(DRV_GLOBAL_BASE + (sizeof(AUDIO_GLOBALS) * index) + PLAY_ADDRESS_OFFSET) == (ULONG)NULL ){
		    // DMA Transmitted Interrupts Disable
			WRITE_REGISTER_ULONG(SH7770_DMAC_REGBASE + DMAC_DINTMR_OFFSET,
				READ_REGISTER_ULONG(SH7770_DMAC_REGBASE + DMAC_DINTMR_OFFSET) & ~((ULONG)1 << pch));

		    // DMA Transmitted Interrupts flag Clear
		    WRITE_REGISTER_ULONG(SH7770_DMAC_REGBASE + DMAC_DINTCR_OFFSET, (ULONG)1 << pch);
			READ_REGISTER_ULONG(SH7770_DMAC_REGBASE + DMAC_DINTMR_OFFSET);		// Coherency measures

	        // HSSI2 TxDMA Disable
			WRITE_REGISTER_ULONG(SSI2_REGBASE + SSI_CR,
				READ_REGISTER_ULONG(SSI2_REGBASE + SSI_CR) & SSI_CRMASK );
		}

		return SYSINTR_HSSI2;
    }

    // set Record-interrupts flag (=1)
    WRITE_REGISTER_ULONG(DRV_GLOBAL_BASE + (sizeof(AUDIO_GLOBALS) * index) + ININT_OFFSET, (ULONG)1);

    // set Playback-interrupts flag (=0)
//    WRITE_REGISTER_ULONG(DRV_GLOBAL_BASE + (sizeof(AUDIO_GLOBALS) * index) + OUTINT_OFFSET, (ULONG)0);

    // DMA Interrupt flag (for OEMInterruptEnable, OEMInterruptDone)
    WRITE_REGISTER_UCHAR(DRV_GLOBAL_BASE + DMA_INTERRUPT_FLG_OFFSET + ch, (ULONG)1);

    return SYSINTR_HSSI2;
}
#pragma optimize("", on)

⌨️ 快捷键说明

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