📄 mcc.c
字号:
usiTxDest= usiTxSrc ^ 0x0001; //invert lsb
/* Copy SIRAM original <-> shadow for Rx and Tx */
for (ucCh=stMcc1SILast.ucChannum;ucCh<(stMcc1SILast.ucChannum+stMcc1SILast.ucBlocksize);ucCh++)
{
pstIMM->t_aSIRAM[SI1].avusiRxSIRAM[ucCh+(usiRxDest*MCC1_SI_ENTRIES)] =
pstIMM->t_aSIRAM[SI1].avusiRxSIRAM[ucCh+(usiRxSrc *MCC1_SI_ENTRIES)];
pstIMM->t_aSIRAM[SI1].avusiTxSIRAM[ucCh+(usiTxDest*MCC1_SI_ENTRIES)] =
pstIMM->t_aSIRAM[SI1].avusiTxSIRAM[ucCh+(usiTxSrc *MCC1_SI_ENTRIES)];
}
/*
Set Tx/Rx internal state (TSTATE/RSTATE):
bit00-01 : reserved = 00
bit02 : snooping (only for 60x bus) = 0 => no snooping
bit03-04 : byte odering = 11 => big-endian
bit05 : transfer code for SDMA access = 0 => not needed here
bit06 : data bus indicator = 1 => local bus SDMA
bit07 : BD & Irq circ. tables bus indicator = 1 => local bus SDMA
bit08-31 : fixed bits = 0x800000
*/
switch (e_Opcode)
{
case TXRX_MCC:
for (ucCh=ucChanNum; ucCh<(ucChanNum+ucBlockSize); ucCh++)
{
pstMCCmch = (t_MChPRAM*) (IMM_BASE + 64*ucCh);
pstMCCmch->vuliTState = 0x1B800000; //Big endian, local bus for BD and data
pstMCCmch->vuliRState = 0x1B800000; //Big endian, local bus for BD and data
pstIMM->t_aSIRAM[SI1].avusiTxSIRAM[ucCh+(usiTxDest*MCC1_SI_ENTRIES)] |= 0x8000 | (ucCh << 5);
pstIMM->t_aSIRAM[SI1].avusiRxSIRAM[ucCh+(usiRxDest*MCC1_SI_ENTRIES)] |= 0x8000 | (ucCh << 5);
}
pstIMM->t_aSIRegs[SI1].vucSICmdR = 0xC0 >> (MCC1_TDM*2); // toggle Rx, Tx SIRAM banks used
break;
case RX_MCC:
for (ucCh=ucChanNum; ucCh<(ucChanNum+ucBlockSize); ucCh++)
{
pstMCCmch = (t_MChPRAM*) (IMM_BASE + 64*ucCh);
pstMCCmch->vuliRState = 0x1B800000; //Big endian, local bus for BD and data
pstIMM->t_aSIRAM[SI1].avusiRxSIRAM[ucCh+(usiRxDest*MCC1_SI_ENTRIES)] |= 0x8000 | (ucCh << 5);
}
pstIMM->t_aSIRegs[SI1].vucSICmdR = 0x80 >> (MCC1_TDM*2); // toggle Rx SIRAM bank used
break;
case TX_MCC:
for (ucCh=ucChanNum; ucCh<(ucChanNum+ucBlockSize); ucCh++)
{
pstMCCmch = (t_MChPRAM*) (IMM_BASE + 64*ucCh);
pstMCCmch->vuliTState = 0x1B800000; //Big endian, local bus for BD and data
pstIMM->t_aSIRAM[SI1].avusiTxSIRAM[ucCh+(usiTxDest*MCC1_SI_ENTRIES)] |= 0x8000 | (ucCh << 5);
}
pstIMM->t_aSIRegs[SI1].vucSICmdR = 0x40 >> (MCC1_TDM*2); // toggle Tx SIRAM bank used
break;
default:
asm(" debug");
}
//Clear Last SIRAM operation storage
stMcc1SILast.ucCmd =1; //open
stMcc1SILast.ucChannum =ucChanNum;
stMcc1SILast.ucBlocksize=ucBlockSize;
return;
}
/*****************************************************************************
* FUNCTION: MCC2_StartChannel()
* PURPOSE: Starts MCC channel using shadow SIRAM capability
* NOTES: None.
* ENTRY: ucChanNum - Channel to be Started
* e_Opcode - What to Start - TX&RX, Rx only or Tx only
* EXIT: None.
*****************************************************************************/
void MCC2_StartChannel(UByte ucChanNum, UByte ucBlockSize, enum e_MCC_CP_CMD_OPCODE e_Opcode)
{
UWord16 usiRxSrc, usiRxDest;
UWord16 usiTxSrc, usiTxDest; //SIRAM original and Shadow indices
UByte ucCh;
t_MChPRAM* pstMCCmch;
t_8101IMM* pstIMM = (t_8101IMM*)IMM_BASE; //pointer to internal memory map.
//msb of channel number must be set => only channels 128...255 allowed
//ucChanNum |= 0x80;
ucChanNum &= 0x7f;
//channel number correct?
if ((ucChanNum+ucBlockSize)>MCC2_NUM_CH)
{
asm(" debug");
}
/* Determine active Rx and Tx SIRAM 0=original, 1=shadow */
usiRxSrc = (pstIMM->t_aSIRegs[SI2].vucSIStR & (0x80>>(MCC2_TDM*2)) ) >> ((3-MCC2_TDM)*2+1);
usiRxDest= usiRxSrc ^ 0x0001; //invert lsb
usiTxSrc = (pstIMM->t_aSIRegs[SI2].vucSIStR & (0x40>>(MCC2_TDM*2)) ) >> ((3-MCC2_TDM)*2);
usiTxDest= usiTxSrc ^ 0x0001; //invert lsb
/* Copy SIRAM original <-> shadow for Rx and Tx */
for (ucCh=stMcc2SILast.ucChannum;ucCh<(stMcc2SILast.ucChannum+stMcc2SILast.ucBlocksize);ucCh++)
{
pstIMM->t_aSIRAM[SI2].avusiRxSIRAM[ucCh+(usiRxDest*MCC2_SI_ENTRIES)] =
pstIMM->t_aSIRAM[SI2].avusiRxSIRAM[ucCh+(usiRxSrc *MCC2_SI_ENTRIES)];
pstIMM->t_aSIRAM[SI2].avusiTxSIRAM[ucCh+(usiTxDest*MCC2_SI_ENTRIES)] =
pstIMM->t_aSIRAM[SI2].avusiTxSIRAM[ucCh+(usiTxSrc *MCC2_SI_ENTRIES)];
}
/*
Set Tx/Rx internal state (TSTATE/RSTATE):
bit00-01 : reserved = 00
bit02 : snooping (only for 60x bus) = 0 => no snooping
bit03-04 : byte odering = 11 => big-endian
bit05 : transfer code for SDMA access = 0 => not needed here
bit06 : data bus indicator = 1 => local bus SDMA
bit07 : BD & Irq circ. tables bus indicator = 1 => local bus SDMA
bit08-31 : fixed bits = 0x800000
*/
switch (e_Opcode)
{
case TXRX_MCC:
for (ucCh=ucChanNum; ucCh<(ucChanNum+ucBlockSize); ucCh++)
{
pstMCCmch = (t_MChPRAM*) (IMM_BASE + 64*(ucCh+128));
pstMCCmch->vuliTState = 0x1B800000; //Big endian, local bus for BD and data
pstMCCmch->vuliRState = 0x1B800000; //Big endian, local bus for BD and data
pstIMM->t_aSIRAM[SI2].avusiTxSIRAM[ucCh+(usiTxDest*MCC2_SI_ENTRIES)] |= 0x8000 | ((ucCh+128) << 5);
pstIMM->t_aSIRAM[SI2].avusiRxSIRAM[ucCh+(usiRxDest*MCC2_SI_ENTRIES)] |= 0x8000 | ((ucCh+128) << 5);
}
pstIMM->t_aSIRegs[SI2].vucSICmdR = 0xC0 >> (MCC2_TDM*2); // toggle Rx, Tx SIRAM banks used
break;
case RX_MCC:
for (ucCh=ucChanNum; ucCh<(ucChanNum+ucBlockSize); ucCh++)
{
pstMCCmch = (t_MChPRAM*) (IMM_BASE + 64*(ucCh+128));
pstMCCmch->vuliRState = 0x1B800000; //Big endian, local bus for BD and data
pstIMM->t_aSIRAM[SI2].avusiRxSIRAM[ucCh+(usiRxDest*MCC2_SI_ENTRIES)] |= 0x8000 | ((ucCh+128) << 5);
}
pstIMM->t_aSIRegs[SI2].vucSICmdR = 0x80 >> (MCC2_TDM*2); // toggle Rx SIRAM bank used
break;
case TX_MCC:
for (ucCh=ucChanNum; ucCh<(ucChanNum+ucBlockSize); ucCh++)
{
pstMCCmch = (t_MChPRAM*) (IMM_BASE + 64*(ucCh+128));
pstMCCmch->vuliTState = 0x1B800000; //Big endian, local bus for BD and data
pstIMM->t_aSIRAM[SI2].avusiTxSIRAM[ucCh+(usiTxDest*MCC2_SI_ENTRIES)] |= 0x8000 | ((ucCh+128) << 5);
}
pstIMM->t_aSIRegs[SI2].vucSICmdR = 0x40 >> (MCC2_TDM*2); // toggle Tx SIRAM bank used
break;
default:
asm(" debug");
}
//Clear Last SIRAM operation storage
stMcc2SILast.ucCmd =1; //open
stMcc2SILast.ucChannum =ucChanNum;
stMcc2SILast.ucBlocksize=ucBlockSize;
return;
}
/*****************************************************************************
* FUNCTION: MCC1_StopChannel()
* PURPOSE: Stop MCC channel using shadow SIRAM capability
* NOTES: None.
* ENTRY: ucChanNum - Channel to be stopped
* e_Opcode - What to Stop - TX&RX, Rx only or Tx only
* EXIT: None.
*****************************************************************************/
void MCC1_StopChannel(UByte ucChanNum, UByte ucBlockSize, enum e_MCC_CP_CMD_OPCODE e_Opcode)
{
UWord16 usiRxSrc, usiRxDest;
UWord16 usiTxSrc, usiTxDest; //SIRAM original and Shadow indices
UByte ucCh;
t_8101IMM* pstIMM = (t_8101IMM*)IMM_BASE; //pointer to internal memory map.
//msb of channel number must be cleared => only channels 0...127 allowed
ucChanNum &= 0x7f;
//channel number correct?
if ((ucChanNum+ucBlockSize)>MCC1_NUM_CH)
{
asm(" debug");
}
/* Determine active Rx and Tx SIRAM 0=original, 1=shadow */
usiRxSrc = (pstIMM->t_aSIRegs[SI1].vucSIStR & (0x80>>(MCC1_TDM*2)) ) >> ((3-MCC1_TDM)*2+1);
usiRxDest= usiRxSrc ^ 0x0001; //invert lsb
usiTxSrc = (pstIMM->t_aSIRegs[SI1].vucSIStR & (0x40>>(MCC1_TDM*2)) ) >> ((3-MCC1_TDM)*2);
usiTxDest= usiTxSrc ^ 0x0001; //invert lsb
/* Copy SIRAM original <-> shadow for Rx and Tx */
for (ucCh=stMcc1SILast.ucChannum;ucCh<(stMcc1SILast.ucChannum+stMcc1SILast.ucBlocksize);ucCh++)
{
pstIMM->t_aSIRAM[SI1].avusiRxSIRAM[ucCh+(usiRxDest*MCC1_SI_ENTRIES)] =
pstIMM->t_aSIRAM[SI1].avusiRxSIRAM[ucCh+(usiRxSrc *MCC1_SI_ENTRIES)];
pstIMM->t_aSIRAM[SI1].avusiTxSIRAM[ucCh+(usiTxDest*MCC1_SI_ENTRIES)] =
pstIMM->t_aSIRAM[SI1].avusiTxSIRAM[ucCh+(usiTxSrc *MCC1_SI_ENTRIES)];
}
/*
set CP command register (CPCR) to stop Tx/Rx of a MCC1 channel:
bit00 : software reset of CP = 0 => no reset
bit01-05 : param. RAM page number = 00111 => offset 0x8700 (MCC1 Param.Ram)
bit06-10 : sub-block code = 11100 => sub-block code for MCC1
bit11-14 : reserved = 0000
bit15 : command semaphore flag = 1 => CP is processing a cmd
bit16-17 : reserved = 00
bit18-25 : MCC channel number = "chan" => MCC channel (0...127)
bit26-27 : reserved = 00
bit28-31 : Opcode = 0100 => Stop Tx
= 1001 => Stop Rx
*/
while (pstIMM->vuliCPCR & 0x00010000); //wait until CP is ready to receive new cmd
switch (e_Opcode)
{
case TXRX_MCC:
for (ucCh=ucChanNum; ucCh<(ucChanNum+ucBlockSize); ucCh++)
{
while (pstIMM->vuliCPCR & 0x00010000); //wait until CP is ready to receive new cmd
pstIMM->vuliCPCR = 0x1F810004 | (ucCh << 6);
pstIMM->t_aSIRAM[SI1].avusiTxSIRAM[ucCh+(usiTxDest*MCC1_SI_ENTRIES)] &= 0x001F;
while (pstIMM->vuliCPCR & 0x00010000); //wait until CP is ready to receive new cmd
pstIMM->vuliCPCR = 0x1F810009 | (ucCh << 6);
pstIMM->t_aSIRAM[SI1].avusiRxSIRAM[ucCh+(usiRxDest*MCC1_SI_ENTRIES)] &= 0x001F;
}
pstIMM->t_aSIRegs[SI1].vucSICmdR = 0xC0 >> (MCC1_TDM*2); // toggle Rx, Tx SIRAM banks used
break;
case RX_MCC:
for (ucCh=ucChanNum; ucCh<(ucChanNum+ucBlockSize); ucCh++)
{
while (pstIMM->vuliCPCR & 0x00010000); //wait until CP is ready to receive new cmd
pstIMM->vuliCPCR = 0x1F810009 | (ucCh << 6);
pstIMM->t_aSIRAM[SI1].avusiRxSIRAM[ucCh+(usiRxDest*MCC1_SI_ENTRIES)] &= 0x001F;
}
pstIMM->t_aSIRegs[SI1].vucSICmdR = 0x80 >> (MCC1_TDM*2); // toggle Rx SIRAM bank used
break;
case TX_MCC:
for (ucCh=ucChanNum; ucCh<(ucChanNum+ucBlockSize); ucCh++)
{
while (pstIMM->vuliCPCR & 0x00010000); //wait until CP is ready to receive new cmd
pstIMM->vuliCPCR = 0x1F810004 | (ucCh << 6);
pstIMM->t_aSIRAM[SI1].avusiTxSIRAM[ucCh+(usiTxDest*MCC1_SI_ENTRIES)] &= 0x001F;
}
pstIMM->t_aSIRegs[SI1].vucSICmdR = 0x40 >> (MCC1_TDM*2); // toggle Tx SIRAM bank used
break;
default:
asm(" debug");
}
//Clear Last SIRAM operation storage
stMcc1SILast.ucCmd =1; //open
stMcc1SILast.ucChannum =ucChanNum;
stMcc1SILast.ucBlocksize=ucBlockSize;
return;
}
/*****************************************************************************
* FUNCTION: MCC2_StopChannel()
* PURPOSE: Stop MCC channel using shadow SIRAM capability
* NOTES: None.
* ENTRY: ucChanNum - Channel to be stopped
* e_Opcode - What to Stop - TX&RX, Rx only or Tx only
* EXIT: None.
*****************************************************************************/
void MCC2_StopChannel(UByte ucChanNum, UByte ucBlockSize, enum e_MCC_CP_CMD_OPCODE e_Opcode)
{
UWord16 usiRxSrc, usiRxDest;
UWord16 usiTxSrc, usiTxDest; //SIRAM original and Shadow indices
UByte ucCh;
t_8101IMM* pstIMM = (t_8101IMM*)IMM_BASE; //pointer to internal memory map.
//msb of channel number must be set => only channels 128...255 allowed
//ucChanNum |= 0x80;
ucChanNum &= 0x7f;
//channel number correct?
if ((ucChanNum+ucBlockSize)>MCC2_NUM_CH)
{
asm(" debug");
}
/* Determine active Rx and Tx SIRAM 0=original, 1=shadow */
usiRxSrc = (pstIMM->t_aSIRegs[SI2].vucSIStR & (0x80>>(MCC2_TDM*2)) ) >> ((3-MCC2_TDM)*2+1);
usiRxDest= usiRxSrc ^ 0x0001; //invert lsb
usiTxSrc = (pstIMM->t_aSIRegs[SI2].vucSIStR & (0x40>>(MCC2_TDM*2)) ) >> ((3-MCC2_TDM)*2);
usiTxDest= usiTxSrc ^ 0x0001; //invert lsb
/* Copy SIRAM original <-> shadow for Rx and Tx */
for (ucCh=stMcc2SILast.ucChannum;ucCh<(stMcc2SILast.ucChannum+stMcc2SILast.ucBlocksize);ucCh++)
{
pstIMM->t_aSIRAM[SI2].avusiRxSIRAM[ucCh+(usiRxDest*MCC2_SI_ENTRIES)] =
pstIMM->t_aSIRAM[SI2].avusiRxSIRAM[ucCh+(usiRxSrc *MCC2_SI_ENTRIES)];
pstIMM->t_aSIRAM[SI2].avusiTxSIRAM[ucCh+(usiTxDest*MCC2_SI_ENTRIES)] =
pstIMM->t_aSIRAM[SI2].avusiTxSIRAM[ucCh+(usiTxSrc *MCC2_SI_ENTRIES)];
}
/*
set CP command register (CPCR) to stop Tx/Rx of a MCC2 channel:
bit00 : software reset of CP = 0 => no reset
bit01-05 : param. RAM page number = 0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -