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

📄 qmcsw.c

📁 这是单板上DPRAM的驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
            _sync_io();                 
            QmcSwGlobalInit();                                  
            splx(imask);
            if(pGCfg->UseTDM==0)return SDE_UNKNOW_CMD;
            if(pGCfg->UseTDM==1)SPLX(pda->si_simode|=0x00000c00;)
            if(pGCfg->UseTDM==2)SPLX(pda->si_simode|=0x0c000000;)                                    
            break;
            
        case SDC_SET_NORMAL_MODE:  
            for(i=0;i<pGCfg->MaxSubChanNum;i++)
            {
                StopReceive(i);
                StopTransmit(i);    
            }
            imask = splx(MAX_ILEV);/* mask interrupt*/
            _sync_io();                 
            QmcSwGlobalInit();                                  
            splx(imask);
            if(pGCfg->UseTDM==0)return SDE_UNKNOW_CMD;
            if(pGCfg->UseTDM==1)SPLX(pda->si_simode&=0xfffff3ff;)
            if(pGCfg->UseTDM==2)SPLX(pda->si_simode&=0xf3ffffff;)
            break;
       
       case SDC_LIMITE_REINIT:
            QmcSwLimitInit();
            break; 
       default:
           return SDE_UNKNOW_CMD;
    }/*end of switch cmd */
    return SDE_OK;
}/*end of QmcSwCtrl*/

static void QmcSwSubIsr(IntEntryStruct *ptr);
static void QmcIsr(void)
{
    USHORT Events,Status;
    PDA  *pda= (PDA *)(GetIMMR() & IO_MAP_MASK);
    IntEntryStruct *pIntrpt;
    Events = pda->Scc_regs[pGCfg->ch].scc_scce;
    pda->Scc_regs[pGCfg->ch].scc_scce = Events; /* clear the event reg*/

    pIntrpt=pGCfg->IntTablePtr;
    if(Events & QMC_GLOB_INT)    /* global interrupt */
    {

        while((pIntrpt->Bit).v)  /* search the int table to find valid entry */
        {
           if(pIntrpt->Bit.rxf||pIntrpt->Bit.bsy||pIntrpt->Bit.txb)
               QmcSwSubIsr(pIntrpt);

           if((pIntrpt->Bit).w)/*process interrupt table */
           {
              pIntrpt->Word16=0;
              (pIntrpt->Bit).w=1;
              pIntrpt=pGCfg->IntTable;
           }
           else
           {
              pIntrpt->Word16=0;
              pIntrpt++;
           }
           pGCfg->IntTablePtr=pIntrpt;
       }/*end for while*/
    } /*end for if global events*/

    if((Events&QMC_GLOB_OV)!=0 || (Events&QMC_GLOB_UN)!=0)
    {
        int i;
        UCHAR map[32];
        memmove(map,MapTable,pGCfg->MaxSubChanNum);
        QmcSwGlobalInit();
        memmove(MapTable,map,pGCfg->MaxSubChanNum);
        for(i=0;i<pGCfg->MaxSubChanNum;i++){
            if(MapTable[i]!=QMCSW_SUBCHAN_INVALID)ReStartReceive(i);  
            ReStartTransmit(i);
        }
    }

    if(Events&QMC_GLOB_IQOV) /* interrupt table is overflow */
    {
        int i;
        for(i=0;i<pGCfg->MaxSubChanNum;i++)
        {
            if(MapTable[i]!=QMCSW_SUBCHAN_INVALID)ReStartReceive(i);  
            ReStartTransmit(i);
        }
    }
} /*end of QmcSwIsr */

static void QmcSwSubIsrSend(int OutChannel)
{
    QmcSubChanParamStruct *ch=(QmcSubChanParamStruct*)((GetIMMR() & IO_MAP_MASK)
                               +0x2000+pGCfg->SubChParamOffset);
    LinkBufStruct *pData;
    for(;;){
        int cur=gDataBuf[OutChannel]->CurSendBD;
        BuffDescType *bd=&(gDataBuf[OutChannel]->pBaseSendBD[cur]);
        if((bd->status&BD_READY)==BD_READY) break;
        if(LinkNumber(&TxLink[OutChannel])==0) break;
        if(bd->address!=0 )
        {
            pData=(LinkBufStruct*)((ULONG)bd->address-8); /* adjust the addr*/
            LinkAppendBuf(&FreeLink,pData);
        }
        pData=LinkGetBuf(&TxLink[OutChannel]);
        bd->address=pData->Data;
        bd->length=pData->Length;
        bd->status&=(~gDataBuf[OutChannel]->SendErrMask);
        bd->status|=BD_READY;
        gDataBuf[OutChannel]->DrvInfo.SendPerNum++;  /*statistic*/
        gDataBuf[OutChannel]->CurSendBD=(gDataBuf[OutChannel]->CurSendBD+1)
                                        %pGCfg->MaxSendBD;
    }
    ch[OutChannel].chamr.pol=1;
}

static void QmcSwSubIsr(IntEntryStruct *ptr)
{
    USHORT Status;
    LinkBufStruct *pData;
    int InChannel=ptr->Bit.chnum;
    int OutChannel;
    
    if((ptr->Bit.rxf||ptr->Bit.bsy))
    {
        gDataBuf[InChannel]->DrvInfo.TotalRecvInt++; /* statistic */       
        OutChannel=MapTable[InChannel];
        if((OutChannel==QMCSW_SUBCHAN_OPERATE)
           &&(gDataBuf[InChannel]->RecvEv!=NULL)
           &&(gDataBuf[InChannel]->RecvTid!=NULL))
        {  
          ev_send(gDataBuf[InChannel]->RecvTid,gDataBuf[InChannel]->RecvEv);
          if(ptr->Bit.bsy) ReStartReceive(InChannel);
        } 
        else
        {        
          for(;;)
          {
            BuffDescType *bd=&(gDataBuf[InChannel]->pBaseRecvBD \
                            [gDataBuf[InChannel]->CurRecvBD]);
            Status=bd->status;
            if((Status&BD_EMPTY)==BD_EMPTY) break;
            if(((Status&gDataBuf[InChannel]->RecvErrMask)==0)
                &&(bd->length>2)
                &&(OutChannel<pGCfg->MaxSubChanNum)
                &&(OutChannel>=0)    
            )
            {
                if(LinkNumber(&FreeLink)==0) break;
                if(bd->address!=0)
                { 
                   pData=(LinkBufStruct*)((ULONG)bd->address-8);/*adjust the addr*/
                   pData->Length=bd->length-2;         
                   LinkAppendBuf(&TxLink[OutChannel],pData);
                   gDataBuf[OutChannel]->DrvInfo.SendTryNum++; /* statistic */
                }
                pData=(LinkBufStruct*)LinkGetBuf(&FreeLink);
                bd->address=pData->Data;
            }
            if((Status&gDataBuf[InChannel]->RecvErrMask)!=0)
            {
                int i;
                gDataBuf[InChannel]->DrvInfo.RecvError++; /*statistic */  
                for(i=0;i<=15;i++)
                    if(Status&(0x8000L>>i))
                        gDataBuf[InChannel]->DrvInfo.RecvBDStat[i]++;
            }
            else
                gDataBuf[InChannel]->DrvInfo.RecvNum++; /*statistic */              
            
            bd->status&=(~gDataBuf[InChannel]->RecvErrMask);
            bd->status|=BD_EMPTY;
            gDataBuf[InChannel]->CurRecvBD=(gDataBuf[InChannel]->CurRecvBD+1)
                                        %pGCfg->MaxRecvBD;                                             
        } /* end of recv */
        if(ptr->Bit.bsy) ReStartReceive(InChannel);
        if((OutChannel>=0)
           &&(OutChannel<pGCfg->MaxSubChanNum))
           QmcSwSubIsrSend(OutChannel);
      } 
    } /* end of receive */

/* start to process send */
    if(ptr->Bit.txb) 
    {  
        gDataBuf[InChannel]->DrvInfo.TotalSendInt++;
        if((gDataBuf[InChannel]->SendEv!=NULL)/*   if set ev and id then this*/
          &&(gDataBuf[InChannel]->SendTid!=NULL))/* channel process by up procedure*/
            ev_send(gDataBuf[InChannel]->SendTid,gDataBuf[InChannel]->SendEv);         
        QmcSwSubIsrSend(InChannel); /* send intr */
    }   
} /*end of QmcSwSubIsr()*/

char *QmcSwBspInit(int DEV, char *FreeMemPtr,QmcSwCfgStruct *gcfg)
{  
    int i;
    
    pGCfg=(QmcSwCfgStruct*)FreeMemPtr;   /* need to add check param */
    InstallSD(DEV,QmcSwRead,QmcSwWrite,QmcSwCntrl,FreeMemPtr);
    memmove((char*)pGCfg,(char*)gcfg,sizeof(QmcSwCfgStruct));
    FreeMemPtr+= sizeof(QmcSwCfgStruct);
    pGCfg->UncachedBuffer
         =(char*)AllocUncachedBuffer(pGCfg->MaxBufNum
          *(sizeof(LinkBufStruct)+pGCfg->MaxBufLen-LINK_DATA_BUF_LEN),64);
    pGCfg->BDTable
        =(char*)AllocUncachedBuffer((pGCfg->MaxRecvBD+pGCfg->MaxSendBD)
         *pGCfg->MaxSubChanNum*sizeof(BuffDescType),64);
    pGCfg->IntTable
        =(IntEntryStruct*)AllocUncachedBuffer(pGCfg->MaxIntEty \
         *sizeof(IntEntryStruct),64);
    pGCfg->IntTablePtr=pGCfg->IntTable;
    for(i=0;i<pGCfg->MaxSubChanNum;i++)
    {
        gDataBuf[i]=(DataBufStruct*)FreeMemPtr;
        memset(gDataBuf[i],0,sizeof(DataBufStruct));  
        FreeMemPtr+=sizeof(DataBufStruct);
    }    
    QmcSwGlobalInit();
    memcpy(FreeMemPtr,"***QMCSW",8);
    FreeMemPtr += 8;
    return FreeMemPtr;
}

void QmcSwLimitInit()
{
 
  UCHAR map[32];
  int i,imax;
  for(i=0;i<pGCfg->MaxSubChanNum;i++)
  {
     StopTransmit(i);
     StopReceive(i);
  } 	 
  (*(pGCfg->InitTDM))();
  imax=splx(MAX_ILEV);
  memmove(map,MapTable,pGCfg->MaxSubChanNum);
  QmcSwGlobalInit();
  memmove(MapTable,map,pGCfg->MaxSubChanNum);
  splx(imax);
  pGCfg->FatalFlag=0;
}	
/* this task is used for single channel loop back test */
/* 发送5个,若接收的错包多于3个,重新初始化*/

ULONG  QmcClkErrNum;
ULONG  QmcLoopErrNum;

void QmcSwBspTestTask(ULONG TaskID)
{
    SDCSetActionStruct SDCSet;
    char TBuf[100];
    char RBuf[272];
    int i,ret,ClkStatus;
    ULONG ev;
    ULONG OldErrorNum,SendNum,RecvCheckErr;
    SDCGetDriverInfoStruct  DrvInfo;
    QmcSubChanParamStruct *ch=(QmcSubChanParamStruct*)((GetIMMR()&IO_MAP_MASK)
                               +0x2000+pGCfg->SubChParamOffset);
    OldErrorNum=0;   
    RecvCheckErr=0;
    SendNum=0;    
    
    QmcClkErrNum=0;
    QmcLoopErrNum=0;
    memset(&SDCSet,0,sizeof(SDCSetActionStruct));
    SDCSet.RecvTid=TaskID;
    SDCSet.RecvEv=QMCSW_BSP_LOOP_RECV_EV;
    SDCSet.SendTid=TaskID;
    SDCSet.SendEv=QMCSW_BSP_LOOP_SEND_EV; 
    BDCntrl(gDataBuf[pGCfg->MaxSubChanNum-1],SDC_SET_ACTION,&SDCSet,
            sizeof(SDCSetActionStruct));
    while(1)
    {
    	
    /* check the clk is right*/
        ClkStatus=(*(pGCfg->QmcSwClkErr))();
        if(ClkStatus==1) 
        {
           pGCfg->FatalFlag=1;
           while((pGCfg->WrInUsing!=0) /*wait until all the channel not inusing */    
		      ||(pGCfg->ReInUsing!=0)) 
	               tm_wkafter(1);
	        QmcClkErrNum++;      
	        QmcSwLimitInit();         /*reinit the channel */  
         }	       	
        sprintf(TBuf,"QMCSW  Single Channel Loop Test"); 
        ret=BDWrite(gDataBuf[pGCfg->MaxSubChanNum-1],TBuf,strlen(TBuf));
        ch[pGCfg->MaxSubChanNum-1].chamr.pol=1;   
        SendNum++;
        if(ret<0) tm_wkafter(1);
	    ret=ev_receive(QMCSW_BSP_LOOP_RECV_EV,EV_WAIT,100,&ev); 
	    if(ret==0)
           if((ev&QMCSW_BSP_LOOP_RECV_EV)==QMCSW_BSP_LOOP_RECV_EV) 
	       {
              for(;;)
	          {
                  memset(RBuf,0,272);
		          ret=BDRead(gDataBuf[pGCfg->MaxSubChanNum-1],RBuf,272);
		          if(ret==SDE_BUF_EMPTY) break;
		          else
		          {
		             ret=memcmp(TBuf,RBuf,strlen(TBuf));/* check the loop back data is right */
		             if(ret!=0) RecvCheckErr++;    /* set the fatal flag */		
		          } 	
	           }/* end for*/		   
           }
           else  pGCfg->FatalFlag=1; /* receive unknown event */
         else  pGCfg->FatalFlag=1;  /* evreceive time out */ 
         if(SendNum%5==0)
         { 
             BDCntrl(gDataBuf[pGCfg->MaxSubChanNum-1],SDC_GET_DRIVER_INFO,&DrvInfo,sizeof(SDCGetDriverInfoStruct));
             if((DrvInfo.RecvError-OldErrorNum+RecvCheckErr)>3)
                pGCfg->FatalFlag=1;
             OldErrorNum=DrvInfo.RecvError;  
             RecvCheckErr=0;                
         }             	
         if((pGCfg->FatalFlag==1)&&(SendNum%5==0))
         {
           while((pGCfg->WrInUsing!=0) /*wait until all the channel not inusing */    
		      ||(pGCfg->ReInUsing!=0)) 
	               tm_wkafter(1);
	        QmcSwLimitInit();         /*reinit the channel */  
	        QmcLoopErrNum++;
         }	                  
         tm_wkafter(100);    
     }	     
}	 

⌨️ 快捷键说明

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