📄 hssi_isr.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 + -