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

📄 mcc_int.c

📁 ANSI C 源代码 WISD MSC8101的MCC驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
     
        // If handling one buffer per IRQ then simple -> clear the BD
        // However handling multi buffers per frame/subframe interrupt...             
        // So, clear BDs between the current interrupt & previous one handled
        i=gusiMcc1TxbufCtr[ucChan];
        for(;;)
        {
          /*-----------------------------------------------*/
          /* Clear BDs between this int and previous one   */
          /*-----------------------------------------------*/
          pstMCC1->astTxChan[ucChan].astBufD[i].usiBdCstatus |= 0x8000;
          status = pstMCC1->astTxChan[ucChan].astBufD[i].usiBdCstatus;
          if (status & 0x2000)  // if wrap set, wrap counts
            i=0; 
          else
            i++;
          if (status & 0x1000)  // if interrupt set, finish
            break;
        }
                                            
        // Update buffer counter record 
        gusiMcc1TxbufCtr[ucChan] = i;

      }
      else
      {
        //wrong channel number
        asm(" debug");
      }
      if (++gusiMcc1TintCtr==MCC1_TINT_NUM) gusiMcc1TintCtr=0;

      pstIMM->t_aIORegs[PORTA].vuliPDat &= ~0x00000007;//resets PA29-31 to 0 

      gusiMcc1TxIntcount++;        // debug aid
      gusiMcc1TxIrqCtr[ucChan]++;  // debug aid                            
    }
  }
  
  if (gusiMcc1RxIntcount & 0x0080) LED(GREEN_ON);
  else                             LED(GREEN_OFF);

  pstIMM->t_aIORegs[PORTA].vuliPDat ^= 0x00000008; //toggle PA28 output (logic analyzer) 
  gusiMcc1TotalIntcount++; // debug aid

  return;
}


/*****************************************************************************
* FUNCTION: MCC2_Interrupt()
* PURPOSE:  Manages MCC2 interrupts, Tx/Rx BDs and checks loopback data.           
* NOTES:    None.
* ENTRY:    None
* EXIT:     None. 
*****************************************************************************/
#pragma interrupt MCC2_Interrupt()
void MCC2_Interrupt(void)
{
  /*
    This function is only called when a SIC/MCC2 interrupt occurs.
  */
  
  UWord32*  puliMCC2IrqTableBase;
  t_Mcc2BDRings*  pstMCC2;
  UByte   ucChan;
  UWord16 usiMCCE;
  Word16  i,pass, status;
  t_8101IMM *pstIMM = (t_8101IMM*)IMM_BASE; // Pointer to internal memory

  pstIMM->t_aIORegs[PORTA].vuliPDat ^= 0x00000080; //toggle PA24 output (logic analyzer)  

  usiMCCE=pstIMM->t_aSIRegs[MCC2].vusiMCCE;        //read event cause
  if(!(usiMCCE & 0x4000) && !(usiMCCE & 0x0004))   //Catch Unintentional Interrupts
    asm(" debug");   
   
  
  /*************/
  /*** RINT0 ***/
  /*************/
  if (usiMCCE & 0x4000) //RINT0 interrupt ?
  { 
    pstMCC2 = (t_Mcc2BDRings*)(MCC2_BDRINGS_BASE-LOCAL_BASE);    
    puliMCC2IrqTableBase = (UWord32*)(MCC2_RINT0_BASE-LOCAL_BASE);
    
    pstIMM->t_aSIRegs[MCC2].vusiMCCE = 0x4000; //clear RINT0 irq flag in MCCE2-reg.

    // Read Int Q entry from core side
    while(*(puliMCC2IrqTableBase+gusiMcc2Rint0Ctr)&0x80000000)
    {
      if (*(puliMCC2IrqTableBase+gusiMcc2Rint0Ctr) & 0x00020000)
        asm(" debug"); // BSY indicates an overrun

      //get channel number from bits 18-25:
      ucChan = ((UByte)(*(puliMCC2IrqTableBase+gusiMcc2Rint0Ctr)>>6)) & 0x7f;
      *(puliMCC2IrqTableBase+gusiMcc2Rint0Ctr) &= 0x40000000; //Reset irq circ. table entry
      pstIMM->t_aIORegs[PORTA].vuliPDat |= ((ucChan&0x00000007)<<4);//sets up PA25-27 with chan-code 

      if (ucChan<MCC2_NUM_CH)
      {

        /*-----------------------------------------------*/
        /* Multiple Buffer and BD Handling per Interrupt */
        /*-----------------------------------------------*/
       
        // If handling one buffer per IRQ then simple -> clear the BD
        // However handling multi buffers per frame/subframe interrupt...             
        // So, clear BDs between the current interrupt & previous one handled
        i=gusiMcc2RxbufCtr[ucChan];
        for(;;)
        {
          /*-----------------------------------------------*/
          /* COMPARE RX BUFFER WITH TX BUFFER              */
          /*-----------------------------------------------*/
          pass=CompareBuffers((UByte*)(pstMCC2->astRxChan[ucChan].astBufD[i].uliBdAddr - LOCAL_BASE),
                              (UByte*)(pstMCC2->astTxChan[ucChan].astBufD[i].uliBdAddr - LOCAL_BASE),
                              (UByte )pstMCC2->astTxChan[ucChan].astBufD[i].usiBdLength);

          if (!pass) 
          {
            LED(RED_OFF);
            asm(" debug");
          }
          
          /*-----------------------------------------------*/
          /* Clear BDs between this int and previous one   */
          /*-----------------------------------------------*/
          pstMCC2->astRxChan[ucChan].astBufD[i].usiBdCstatus |= 0x8000;
          pstMCC2->astRxChan[ucChan].astBufD[i].usiBdLength = 0;          
          status = pstMCC2->astRxChan[ucChan].astBufD[i].usiBdCstatus;
          if (status & 0x2000)  // if wrap set, wrap counts
            i=0; 
          else
            i++;
          if (status & 0x1000)  // if interrupt, finish
            break;
        }                                            

        // Wrap buffer counter record if last buffer
        gusiMcc2RxbufCtr[ucChan] = i;
                               
      }
      else
      {
        asm(" debug");
      }
      if (++gusiMcc2Rint0Ctr==MCC2_RINT0_NUM) gusiMcc2Rint0Ctr=0;

      pstIMM->t_aIORegs[PORTA].vuliPDat &= ~0x00000070;//resets PA25-27 to 0 

      gusiMcc2RxIntcount++;        // debug aid
      gusiMcc2RxIrqCtr[ucChan]++;  // debug aid                            
        
    }
  }      
  

  /*************/
  /*** TINT  ***/
  /*************/
  if (usiMCCE & 0x0004)  // TINT Interrupt
  {
    pstMCC2 = (t_Mcc2BDRings*)(MCC2_BDRINGS_BASE-LOCAL_BASE);    
    puliMCC2IrqTableBase = (UWord32*)(MCC2_TINT_BASE-LOCAL_BASE);

    pstIMM->t_aSIRegs[MCC2].vusiMCCE = 0x0004; //clear TINT irq flag in MCCE1-reg.

    // Read Int Q entry from core side
    while(*(puliMCC2IrqTableBase+gusiMcc2TintCtr)&0x80000000)
    {
    
      if (*(puliMCC2IrqTableBase+gusiMcc2Rint0Ctr) & 0x00200000)
        asm(" debug"); // UN indicates an underrun

      //get channel number from bits 18-25:
      ucChan = ((UByte)(*(puliMCC2IrqTableBase+gusiMcc2TintCtr)>>6)) & 0x7f;
      *(puliMCC2IrqTableBase+gusiMcc2TintCtr) &= 0x40000000; //Reset irq circ. table entry
//    pstIMM->t_aIORegs[PORTA].vuliPDat |= ucChan&0x00000007;//sets up PA29-31 with chan-code 
 
      if (ucChan<MCC2_NUM_CH)
      {       
        /*-----------------------------------------------*/
        /* Multiple Buffer and BD Handling per Interrupt */
        /*-----------------------------------------------*/
     
        // If handling one buffer per IRQ then simple -> clear the BD
        // However handling multi buffers per frame/subframe interrupt...             
        // So, clear BDs between the current interrupt & previous one handled
        i=gusiMcc2TxbufCtr[ucChan];
        for(;;)
        {
          /*-----------------------------------------------*/
          /* Clear BDs between this int and previous one   */
          /*-----------------------------------------------*/
          pstMCC2->astTxChan[ucChan].astBufD[i].usiBdCstatus |= 0x8000;
          status = pstMCC2->astTxChan[ucChan].astBufD[i].usiBdCstatus;
          if (status & 0x2000)  // if wrap set, wrap counts
            i=0; 
          else
            i++;
          if (status & 0x1000)  // if interrupt set, finish
            break;
        }
                                            
        // Update buffer counter record 
        gusiMcc2TxbufCtr[ucChan] = i;

      }
      else
      {
        //wrong channel number
        asm(" nop");
        asm(" debug");
      }
      if (++gusiMcc2TintCtr==MCC2_TINT_NUM) gusiMcc2TintCtr=0;

      pstIMM->t_aIORegs[PORTA].vuliPDat &= ~0x00000007;//resets PA29-31 to 0 

      gusiMcc2TxIntcount++;        // debug aid
      gusiMcc2TxIrqCtr[ucChan]++;  // debug aid                            
    }
  }
  
  if (gusiMcc2RxIntcount & 0x0080) LED(RED_ON);
  else                             LED(RED_OFF);

  pstIMM->t_aIORegs[PORTA].vuliPDat ^= 0x00000080; //toggle PA24 output (logic analyzer) 
  gusiMcc2TotalIntcount++; // debug aid

  return;
}


/*****************************************************************************
* FUNCTION: CompareBuffers()
* PURPOSE:  Compares 2 Buffers.           
* NOTES:    None.
* ENTRY:    UByte *pucBuf1 - Pointer to source buffer
*           UByte *pucBuf2 - Pointer to destination buffer
*           UWord16 usiLen - Length for comparison
* EXIT:     None. 
*****************************************************************************/
Word16 CompareBuffers(UByte *pucBuf1, UByte *pucBuf2, UWord16 usiLen)
{
  Word16 usiI;
  Word16 usiMatch=1;
  
  for (usiI=0; usiI<usiLen; usiI++)
  {
      if (*pucBuf1++ != *pucBuf2++)
        usiMatch =0;  
  }  
  return (usiMatch);
}


⌨️ 快捷键说明

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