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

📄 mcc.c

📁 ANSI C 源代码 WISD MSC8101的MCC驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
  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 + -