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

📄 qmc.c

📁 这是单板上DPRAM的驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "board.h"
#include "sdev.h"
#include "hdlc.h"
#include "qmc.h"

#define regs(ch) pda->Scc_regs[ch]

#if  QMCPOLLING
void *  Global_pGCfg;
#endif
/*---------Local functions-----------------------------*/
static void ReInitAllRecvCh(QmcGlobalCfgStruct *pGCfg);
static void ReInitAllSendCh(QmcGlobalCfgStruct *pGCfg);
static void QmcResetSubChan(DataBufStruct *pData,QmcSubChanCfgStruct *);
static void QmcStopOp(QmcSubChanCfgStruct *pCfg);
static void QmcStartOp(QmcSubChanCfgStruct *pCfg);
static void QmcSubChanIsr(void *pDataBuf,IntEntryStruct *pIES);

#ifndef QMCPOLLING
static void QmcIsr(void *pDataBuf);
#endif

static void QmcLimitReInit(QmcGlobalCfgStruct *pGCfg);


static void QmcResetSubChan(DataBufStruct *pData,QmcSubChanCfgStruct *pCfg)
{
    int i;
/*    QmcGlobalCfgStruct *pGCfg=pCfg->pGCfg;*/
    QmcSubChanParamStruct* scpm= 
        (QmcSubChanParamStruct*)((GetIMMR() & IO_MAP_MASK)+0x2000); 
    scpm[pCfg->ch].tstate=0x30000000;
    scpm[pCfg->ch].zistate=0x100;
    scpm[pCfg->ch].tbptr=scpm[pCfg->ch].tbase;
    scpm[pCfg->ch].rbptr=scpm[pCfg->ch].rbase;
    pData->CurRecvBD=pData->CurSendBD=0;     
    for(i=0;i<pData->MaxRecvBD;i++)
    pData->pBaseRecvBD[i].status = BD_EMPTY|BD_INTR;
    if(i>0)pData->pBaseRecvBD[i-1].status |= BD_WRAP;
    for(i=0;i<pData->MaxSendBD;i++)
    pData->pBaseSendBD[i].status = BD_INTR|BD_LAST|HDLC_TX_CRC;
    if(i>0)pData->pBaseSendBD[i-1].status |= BD_WRAP;
}

static void QmcStopOp(QmcSubChanCfgStruct *pCfg)
{
	CPM_CMD(QMC_RESERVE|QMC_STOP_RX|((pCfg->ch)<<2));
	CPM_CMD(QMC_RESERVE|QMC_STOP_TX|((pCfg->ch)<<2));
}

static void QmcStartOp(QmcSubChanCfgStruct *pCfg)
{
   unsigned short k;
   QmcGlobalParamStruct *gmp  =(QmcGlobalParamStruct *)((GetIMMR()&IO_MAP_MASK)
       +0x3C00+0x100*pCfg->pGCfg->ch);
   QmcSubChanParamStruct* scpm= 
        (QmcSubChanParamStruct*)((GetIMMR() & IO_MAP_MASK)+0x2000); 
   
   k=pCfg->ch;
   if(scpm[k].chamr.ent==0)/*do if channel is deactive*/
   {
            
      scpm[k].tstate=0x30000000;
      scpm[k].zistate=0x100;
      gmp->tsatt[k].v=1; 
      scpm[k].chamr.ent=1;              
   }
   if(scpm[k].chamr.pol==0)
        scpm[k].chamr.pol=1;   /*start tx*/
   scpm[k].rstate=0x31000000;  /*start rev*/
   scpm[k].zdstate=0x0000080;
}

int QmcRead(void *pDataBuf,void *pBuf, int MaxLen)         
{   
    int ret;
    /* DataBufStruct*  pData=(DataBufStruct *)pDataBuf; */
    /* QmcSubChanCfgStruct*  pCfg =(QmcSubChanCfgStruct *)(pData+1); */
    ret=BDRead(pDataBuf,pBuf,MaxLen);
    if(ret>2)return ret-2;    /* sub 2 bytes of CRC */
    else if(ret>0)return SDE_INVALID_PACKET;  
    else return ret;
}

int QmcWrite(void *pDataBuf,void *pBuf, int MaxLen)         
{   
    int ret;
    DataBufStruct*  pData=(DataBufStruct *)pDataBuf;
    QmcSubChanCfgStruct*  pCfg =(QmcSubChanCfgStruct *)(pData+1);
    QmcSubChanParamStruct* scpm= 
        (QmcSubChanParamStruct*)((GetIMMR() & IO_MAP_MASK)+0x2000);
    ret=BDWrite(pDataBuf,pBuf,MaxLen);
    scpm[pCfg->ch].chamr.pol=1;   
    return ret; 
}

static void QmcSubChanIsr(void *pDataBuf,IntEntryStruct *pIES)
{
    IntEntryStruct ev=*pIES;
    DataBufStruct*  pData=(DataBufStruct *)pDataBuf;
    PDA  *pda = (PDA *)(GetIMMR() & IO_MAP_MASK);
/*    QmcSubChanCfgStruct*  pCfg=(QmcSubChanCfgStruct *)(pData+1); keep for test*/
    QmcSubChanParamStruct *pSubChanParam
    =(QmcSubChanParamStruct *)((char*)pda+0x2000);

    if( ev.Bit.bsy==1 )
    {
       pSubChanParam[ev.Bit.chnum].rstate=0x31000000;
       pSubChanParam[ev.Bit.chnum].zdstate=0x0000080;
    }

    if( ev.Bit.un==1 )    
    {
        pSubChanParam[ev.Bit.chnum].chamr.pol=1;   
        return;
    }

    if( ev.Bit.rxf == 1 || ev.Bit.rxb == 1|| ev.Bit.bsy==1)
    {
        pData->DrvInfo.TotalRecvInt++;
        if( (pData->RecvEv!=NULL) && (pData->RecvTid!=NULL) )
        {    
            ev_send(pData->RecvTid,pData->RecvEv);
        }
       if( pData->RecvQID!=NULL )
        {    
            q_send(pData->RecvQID,pData->RecvMessage);
        }  
    }
    if( ev.Bit.txb == 1 )
    {
        pData->DrvInfo.TotalSendInt++;
        if( (pData->SendEv!=NULL) && (pData->SendTid!=NULL) )
        {
            ev_send(pData->SendTid,pData->SendEv);
        }
        if( pData->SendQID!=NULL )
        {    
            q_send(pData->SendQID,pData->SendMessage);
        }
    }
}

static void ReInitAllRecvCh(QmcGlobalCfgStruct *pGCfg)
{
    USHORT i;
    PDA  *pda = (PDA *)(GetIMMR() & IO_MAP_MASK);
    QmcSubChanParamStruct *pSubChanParam
        =(QmcSubChanParamStruct *)((char*)pda+0x2000);
    DataBufStruct*  pData;
    QmcSubChanCfgStruct*  pCfg;
    for(i=0;i<pGCfg->MaxSubChanNum;i++)
    {
       pData=(DataBufStruct*)pGCfg->IsrParam[i+pGCfg->SubChParamOffset/64];
       pCfg =(QmcSubChanCfgStruct *)(pData+1);
       pSubChanParam[pCfg->ch].rstate=0x31000000;
       pSubChanParam[pCfg->ch].zdstate=0x0000080;
    }
    pda->Scc_regs[pGCfg->ch].scc_gsmra|=0x00000020;/* Enable rx */
}

static void ReInitAllSendCh(QmcGlobalCfgStruct *pGCfg)
{
    USHORT i;
    PDA  *pda = (PDA *)(GetIMMR() & IO_MAP_MASK);
    QmcSubChanParamStruct *pSubChanParam
        =(QmcSubChanParamStruct *)((char*)pda+0x2000);
    DataBufStruct*  pData;
    QmcSubChanCfgStruct*  pCfg;
    for(i=0;i<pGCfg->MaxSubChanNum;i++)
    {
        pData=(DataBufStruct*)pGCfg->IsrParam[i+pGCfg->SubChParamOffset/64];
        pCfg =(QmcSubChanCfgStruct *)(pData+1);   
        pSubChanParam[pCfg->ch].chamr.pol=1;
    }
    pda->Scc_regs[pGCfg->ch].scc_gsmra|=0x00000010;/* Enable tx */
}

#ifndef QMCPOLLING
static void QmcIsr(void *pDataBuf)
{
    unsigned short Events;
    QmcGlobalCfgStruct *pGCfg=(QmcGlobalCfgStruct *)pDataBuf;
    PDA  *pda = (PDA *)(GetIMMR() & IO_MAP_MASK);

    Events = pda->Scc_regs[pGCfg->ch].scc_scce;
    pda->Scc_regs[pGCfg->ch].scc_scce = Events; /* clear the event register */
    if( (Events & QMC_GLOB_OV)==QMC_GLOB_OV )
    {
        ReInitAllRecvCh(pGCfg);
        return;
    }

    if( ((Events & QMC_GLOB_UN)==QMC_GLOB_UN) )
    {
        ReInitAllSendCh(pGCfg);
        return;
    }
    if(   ((Events & QMC_GLOB_INT )==QMC_GLOB_INT)    /* global interrupt */  
       || ((Events & QMC_GLOB_IQOV)==QMC_GLOB_IQOV)   )
    {
        while((pGCfg->IntTablePtr->Bit).v)  /* search the interrupt table */  
        {
            ULONG sub=pGCfg->IntTablePtr->Bit.chnum;
            QmcSubChanIsr(pGCfg->IsrParam[sub],pGCfg->IntTablePtr);
            pGCfg->IntTablePtr->Word16&=0x4000;
            if(1 == pGCfg->IntTablePtr->Bit.w)
                pGCfg->IntTablePtr=pGCfg->IntTable;
            else
                pGCfg->IntTablePtr++;
        } 
    }/* end of if */
    if((Events & QMC_GLOB_IQOV)==QMC_GLOB_IQOV )
    {
        ReInitAllRecvCh(pGCfg);/* end of if */
    }
}  /* end of QmcIsr */          

#else
void QmcIsr(void *pDataBuf)
{
    unsigned short Events;
    QmcGlobalCfgStruct *pGCfg=(QmcGlobalCfgStruct *)pDataBuf;
    PDA  *pda = (PDA *)(GetIMMR() & IO_MAP_MASK);

    Events = pda->Scc_regs[pGCfg->ch].scc_scce;
    pda->Scc_regs[pGCfg->ch].scc_scce = Events; /* clear the event register */
    if( (Events & QMC_GLOB_OV)==QMC_GLOB_OV )
    {
        ReInitAllRecvCh(pGCfg);
        return;
    }

    if( ((Events & QMC_GLOB_UN)==QMC_GLOB_UN) )
    {
        ReInitAllSendCh(pGCfg);
        return;
    }
    if(   ((Events & QMC_GLOB_INT )==QMC_GLOB_INT)    /* global interrupt */  
       || ((Events & QMC_GLOB_IQOV)==QMC_GLOB_IQOV)   )
    {
        while((pGCfg->IntTablePtr->Bit).v)  /* search the interrupt table */  
        {
            ULONG sub=pGCfg->IntTablePtr->Bit.chnum;
            QmcSubChanIsr(pGCfg->IsrParam[sub],pGCfg->IntTablePtr);
            pGCfg->IntTablePtr->Word16&=0x4000;
            if(1 == pGCfg->IntTablePtr->Bit.w)
                pGCfg->IntTablePtr=pGCfg->IntTable;
            else
                pGCfg->IntTablePtr++;
        } 
    }/* end of if */
    if((Events & QMC_GLOB_IQOV)==QMC_GLOB_IQOV )
    {
        ReInitAllRecvCh(pGCfg);/* end of if */
    }
}
#endif

void QmcSubChanInit(void *pDataBuf, QmcSubChanCfgStruct *cfg)
{
    int i;
    BuffDescType   *temp_bufdes;
    char *pRecvBuf,*pSendBuf;
    DataBufStruct*  pData=(DataBufStruct *)pDataBuf;
    QmcSubChanCfgStruct*  pCfg =(QmcSubChanCfgStruct *)(pData+1);
    QmcGlobalCfgStruct *  pGCfg=cfg->pGCfg;
    QmcSubChanParamStruct* scpm= 
        (QmcSubChanParamStruct*)((GetIMMR() & IO_MAP_MASK)+0x2000);

/*--------------------------<< Initial data >>-------------------------------*/
    memmove(pCfg,cfg,sizeof(*cfg));
    memset(scpm[pCfg->ch], 0, sizeof(QmcSubChanParamStruct));
    
    /* Step 16. Initialize channel-specific parameters for HDLC */
    pCfg->ch&=0x3F;
    pData->CurRecvBD=0;
    pData->CurSendBD=0;
    pData->MaxRecvBD=pGCfg->MaxRecvBD;
    pData->MaxSendBD=pGCfg->MaxSendBD;
    pData->MaxBufLen=pGCfg->MaxBufLen;
    pData->RecvErrMask=(HDLC_DPLL_ERR|HDLC_GREATER_LEN|HDLC_NOT_ALIGNED
        |HDLC_ABORT_SEQ|HDLC_RX_CRC|HDLC_OVERRUN|HDLC_CD_LOST);
    pData->SendErrMask=(HDLC_UNDERRUN|HDLC_CTS_LOST);
    pData->UncachedBuffer=pRecvBuf=pGCfg->UncachedBuffer
        +(pGCfg->MaxRecvBD+pGCfg->MaxSendBD)*(pCfg->ch-pGCfg->SubChParamOffset/64)
        *pGCfg->MaxBufLen;
    pSendBuf=(char*)(pRecvBuf+( pGCfg->MaxRecvBD)*(pGCfg->MaxBufLen));

/*-------------------------<< stop SCCx operation >>----------------------*/
    QmcStopOp(pCfg); 

/*----------------------<< init SCCx >>-----------------------------------*/
    scpm[pCfg->ch].tbase=(pGCfg->MaxRecvBD+pGCfg->MaxSendBD)*
                         (pCfg->ch-pGCfg->SubChParamOffset/64)*BD_LEN;
    scpm[pCfg->ch].rbase=scpm[pCfg->ch].tbase+pGCfg->MaxSendBD*BD_LEN;
    scpm[pCfg->ch].tstate=0x30000000;
    scpm[pCfg->ch].rstate=0x31000000;  /* we enable it later,in QmcStartOp() */  
    scpm[pCfg->ch].zistate=0x100;     /* HDLC mode */ 
    scpm[pCfg->ch].zdstate=0x80;     /* we enable it later,in QmcStartOp() */           
    scpm[pCfg->ch].intmask=0x1e;      /* enable UN,RXF TXB and BSY interrupt*/  
    scpm[pCfg->ch].mflr= pData->MaxBufLen-8;    /* maximum frame length */  
    scpm[pCfg->ch].tbptr=scpm[pCfg->ch].tbase;
    scpm[pCfg->ch].rbptr=scpm[pCfg->ch].rbase;
  
    /* Step 17. Initialize RxBDs. */
    /* rx */
    temp_bufdes=pData->pBaseRecvBD
        =(BuffDescType *)(pGCfg->BDTable+scpm[pCfg->ch].rbase);
    for(i=0;i<pData->MaxRecvBD;i++)
    {
        temp_bufdes[i].status=BD_EMPTY|BD_INTR;
        temp_bufdes[i].length=0;
        temp_bufdes[i].address=pRecvBuf+i*pData->MaxBufLen;
    }
    if(i>0)temp_bufdes[i-1].status|=BD_WRAP;
   
    /* Step 18. Initialize TxBDs */
    /* tx */
    temp_bufdes=pData->pBaseSendBD
        =(BuffDescType *)(pGCfg->BDTable+scpm[pCfg->ch].tbase);
    for(i=0;i<pData->MaxSendBD;i++)
    {
        temp_bufdes[i].status=BD_INTR|BD_LAST|HDLC_TX_CRC;
        temp_bufdes[i].length=pData->MaxBufLen-2;
        temp_bufdes[i].address=pSendBuf+i*pData->MaxBufLen;
    }
    if(i>0)temp_bufdes[i-1].status|=BD_WRAP;
    pGCfg->IsrParam[pCfg->ch]=pDataBuf;
    
    /* Step 19. Initialize the circular interrupt table */
	/* init the interrupt table */
    for(i=0;i<pGCfg->IntTableLen;i++)            
        pGCfg->IntTable[i].Word16=0;
    if(i>=1)pGCfg->IntTable[i-1].Bit.w=1;
#ifdef QMCPOLLING    
    Global_pGCfg=(void *)pGCfg;
#else    
    SPLX(CpmIsrAddHandler(V_SCC1-pGCfg->ch,QmcIsr,(void *)pGCfg); )
#endif    
    
    /* Step 20. Initialize the channel mode register CHAMR */
	scpm[pCfg->ch].chamr.mode=1;      /* HDLC mode */
    scpm[pCfg->ch].chamr.idlm=0;      /* disable idle frame  */
    scpm[pCfg->ch].chamr.ent=1;       /* enable channel xmit*/ 
    scpm[pCfg->ch].chamr.crc=0;       /* 16 bit crc */         
    scpm[pCfg->ch].chamr.nof=0;       /* 1 flags  */
    scpm[pCfg->ch].chamr.pol=1;       /* enable polling */ 
 /*   QmcStartOp(pCfg); */
}

void QmcGlobalInit(void *pDataBuf, QmcGlobalCfgStruct *cfg)
{
    unsigned long i;
    QmcGlobalCfgStruct   *pCfg =(QmcGlobalCfgStruct *)(pDataBuf);   
    PDA                  *pda  =(PDA *)(GetIMMR() & IO_MAP_MASK);
    QmcGlobalParamStruct *gmp  =(QmcGlobalParamStruct *)((GetIMMR()&IO_MAP_MASK)+0x3C00+0x100*cfg->ch);
    memmove(pCfg,cfg,sizeof(*cfg));
    memset(gmp,0,sizeof(QmcGlobalParamStruct));
    if(pCfg->MaxRecvTSAEntry==0)pCfg->MaxRecvTSAEntry=pCfg->MaxSubChanNum;
    if(pCfg->MaxSendTSAEntry==0)pCfg->MaxSendTSAEntry=pCfg->MaxSubChanNum;
   /* add switch protocols*/   
    
    regs(pCfg->ch).scc_gsmra=0x0;
	CPM_CMD((pCfg->ch)<<(2+4)); /* INIT_RX_TX_PARAMS */
    
	SPLX(pda->si_sigmr&=~((0x04)<<(pCfg->UseTDM-1));)    /*disable static TDMA  */
    pCfg->ch=(pCfg->ch&0x3);
    SPLX(pda->cpmi_cimr&=(~(EN_SCC1 >> pCfg->ch));)/* disable scc interrutp */
    pCfg->IntTablePtr=pCfg->IntTable;
    pda->Scc_regs[pCfg->ch].scc_gsmra &= 0xffffffcf; /*disable rx & tx */
    
	/* Step 1: Initialize the SIMODE (serial interface mode) register. */

⌨️ 快捷键说明

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