📄 sccahdlcdrv.c
字号:
if (NULL == (pSccDev->writeSem = semBCreate (SEM_Q_PRIORITY, SEM_FULL) ) ) goto errExit; if (NULL == (pSccDev->readSem = semBCreate (SEM_Q_PRIORITY, SEM_FULL) ) ) goto errExit; /******************************initian end*******************************************/ if ( (ahdlcDrvNum = iosDevAdd ( & pSccDev->devHdr, devName, ahdlcDrvNum ) ) == ERROR) goto errExit; return (OK); errExit: #ifdef USE_DMA if(NULL != pSccDev->precv_buf_malloc_address) cacheDmaFree ( pSccDev->usr_recv_buf); if(NULL != pSccDev->ptran_buf_malloc_address ) cacheDmaFree ( pSccDev->ptran_buf_malloc_address); #endif return (ERROR); }/******************************************************/static int ahdlcOpen (DEV_HDR *pDev, char *name, int mode){ SCC_AHDLC_DEV * pSccDev = (SCC_AHDLC_DEV * ) pDev ; #ifdef M_DEBUG int i; #endif debug((" \n open dev %s \n" , name)); if ( pDev == NULL ) { errnoSet (2); return (ERROR); } if( pSccDev->opened) { return (ERROR); } pSccDev->opened = TRUE; semGive (pSccDev->writeSem); semGive (pSccDev->readSem); #if 0 if( NULL == ( pSccDev->rsyncSem =semBCreate (SEM_Q_PRIORITY, SEM_FULL) ) ) return (ERROR); if( NULL == ( pSccDev->tsyncSem = semBCreate (SEM_Q_PRIORITY, SEM_FULL) ) ) return (ERROR); #endif /*初始化用户缓冲和读写指针*/ memset( ( char * ) pSccDev->usr_recv_buf , 0, sizeof(BUFM_BUF)*SCC_AHDLC_RECV_BUF_NUM); pSccDev->rbuf_rptr =0; pSccDev->rbuf_wptr =0; init_tranBD(pSccDev); init_recvBD(pSccDev); pSccDev->statistics.pnumCrcec =0; AHDLC_RX_CS(); sccHdlcEnable(pSccDev); /* enable the scc */ #ifdef M_DEBUG debug(("look up rx bd mod ???????? \n")); for(i = 0;i< SCC_NUM_RBD ; i++) { debug((" %x ," , pSccDev->precv_BD[ i ].statusMode & BD_RX_EMPTY_BIT )); if( ( i%8) == 7) debug((" \n")); } debug(("\n")); #endif return ( (int )pDev ); }static int ahdlcRead (int deviceid, char *pBuf, int buflen){ /* 对一些变量进行初始化操作*/ int read_length = ERROR; BUFM_BUF * bufptr ; /* 获得设备描述符并判断*/ SCC_AHDLC_DEV * pSccDev =( SCC_AHDLC_DEV *) deviceid ; assert( (buflen-2) >0); if( pSccDev == (SCC_AHDLC_DEV * )NULL ) { return (ERROR); } bufptr = & pSccDev->usr_recv_buf[pSccDev->rbuf_rptr]; while(0 == bufptr->status) { return 0; /*semTake(pSccDev->readSem, WAIT_FOREVER);*/ } bufptr->len-=2; read_length = bufptr->len < buflen ? bufptr->len : buflen ; bcopy( (const char *)bufptr->body, (char *)pBuf, read_length); /* logMsg(" recv %x,%x \n" , bufptr->body[0],bufptr->body[96] ); printf( "addt rx %x, %x ,%x\n", bufptr->body,txpbbuf, usrbuf); */ bufptr->status = 0; pSccDev->rbuf_rptr++; if( SCC_AHDLC_RECV_BUF_NUM <= pSccDev->rbuf_rptr) pSccDev->rbuf_rptr = 0; pSccDev->ready_to_read =FALSE; return ( read_length ); }static int ahdlcWrite (int deviceid, char *pBuf, int buflen){ /* 对一些变量进行初始化操作*/ int write_length = ERROR; /*BOOL found_error;*/ BUFM_BUF * bufptr ; SCC_AHDLC_BD * pBD; /* 获得设备描述符并判断*/ SCC_AHDLC_DEV * pSccDev =( SCC_AHDLC_DEV *) deviceid ; if( pSccDev == (SCC_AHDLC_DEV * )NULL ) { return (ERROR); } if((0 >=buflen) || ( buflen > (AHDLC_MAX_PKT_LEN))) return(-1); semTake (pSccDev->writeSem , WAIT_FOREVER); pBD = &(pSccDev->ptran_BD[pSccDev->current_tBD]); if( AHDLC_BD_TX_READY_BIT & (pBD->statusMode) ) /* current BD is busy, return without send.*/ { return -1; } /* BD is empty */ AHDLC_TX_CS(); /* set BD length */ pBD->dataLength = buflen; /* copy data to BD's buffer */ bcopy( (const char *)pBuf, (char *)pBD->dataPointer, pBD->dataLength); /* change the current transmite BD */ if( AHDLC_BD_TX_WRAP_BIT & pBD->statusMode ) pSccDev->current_tBD = 0; else pSccDev->current_tBD++; /* set the ready bit .*/ pBD->statusMode |= AHDLC_BD_TX_READY_BIT | AHDLC_BD_TX_INTERRUPT_BIT | AHDLC_BD_TX_LAST_FRAME_BIT ; pSccDev->ready_to_write = FALSE; return (buflen);}static int ahdlcIoctl (int deviceid, int cmd, int arg){ int status = ERROR; SCC_AHDLC_DEV * pSccDev =( SCC_AHDLC_DEV *) deviceid ; EPCFG *cfg; int baudRate; switch(cmd) { case FIOSELECT: /* add node to wakeup list */ status =selNodeAdd (&pSccDev->selWakeupkist, (SEL_WAKEUP_NODE *) arg); if ((selWakeupType ((SEL_WAKEUP_NODE *) arg) == SELREAD )&&(pSccDev->ready_to_read)) selWakeup ((SEL_WAKEUP_NODE *) arg); if ((selWakeupType ((SEL_WAKEUP_NODE *) arg) == SELWRITE )&&(pSccDev->ready_to_write)) selWakeup ((SEL_WAKEUP_NODE *) arg); break; case FIOUNSELECT: /* delete node from wakeup list */ status =selNodeDelete (&pSccDev->selWakeupkist, (SEL_WAKEUP_NODE *) arg); break; case SIO_BAUD_SET: debug(("set bauderate = %d \n", arg)); if (arg >= 1600 && arg <= 38400) /* could go higher... */ { /* calculate proper counter value, then enable BRG */ cfg = getEpCfg(); baudRate = (cfg->sysBrgClkFreq /16 - arg /2) / arg; *pSccDev->pBaud = ( BRGC_CD_MSK &(baudRate << BRGC_CD_SHIFT) ) | BRGC_EN |BRGC_DIV16; status = OK; } else if(arg>38400 && arg <= 115200 ) { cfg = getEpCfg(); baudRate = (cfg->sysBrgClkFreq - arg /2) / arg; *pSccDev->pBaud = ( BRGC_CD_MSK &(baudRate << BRGC_CD_SHIFT) ) | BRGC_EN ; status = OK; } else status = EIO; break; case SIO_BAUD_GET: cfg = getEpCfg(); baudRate = *pSccDev->pBaud; baudRate = ( (1+ ((baudRate & BRGC_CD_MSK)>>BRGC_CD_SHIFT) ) ) * ( 1 + (baudRate & BRGC_DIV16)*15 ); * (int *)arg = cfg->sysBrgClkFreq /baudRate ; status = OK; break; case FIOOPTIONS: if(1 == arg) { AHDLC_TX_CS(); } else { AHDLC_RX_CS(); } status = OK; break; case FIOREADYCHANGE: /* errot get */ memcpy((char *)arg, (char *)&pSccDev->statistics , sizeof(SCC_AHDLC_STATISTIC) ); status = OK; break; case FIONWRITE: /*reset error count*/ bzero((char *)&pSccDev->statistics ,sizeof(SCC_AHDLC_STATISTIC) ); status = OK; break; default : status = ERROR; break; } return status ; }static int ahdlcClose(int deviceid){ /* 获得设备描述符并判断*/ SCC_AHDLC_DEV * pSccDev =( SCC_AHDLC_DEV *) deviceid ; if( pSccDev == (SCC_AHDLC_DEV * )NULL ) { return (ERROR); } /* 关闭中断*/ AHDLC_RX_CS(); sccHdlcDisable(pSccDev); pSccDev->opened = FALSE ; debug((" \n close AHDLC !\n" )); /*释放缓冲区*/}int ahdlcAttach(void){ ahdlcDrv(); ahdlcDevCreate("/ahdlc"); return OK;}/************use for test *************************/void dtt (int data){int i;int j;int k;#define AHDLC_TXD 0x0080#define AHDLC_RXD 0x0040 int immrval; EPCFG *cfg = getEpCfg(); immrval = vxImmrGet(); if(0 == data) { AHDLC_TX_CS(); /* General-purpose I/O.*/ *PAPAR(immrval) &= (~AHDLC_TXD ); /*Select the signal for general-purpose output*/ *PADIR(immrval)|=AHDLC_TXD ; *PADAT(immrval) &= (~AHDLC_TXD ); printf(" CS : 1 ,TXD : 0 \n "); } else if( 1 ==data ) { AHDLC_TX_CS(); /* General-purpose I/O.*/ *PAPAR(immrval) &= (~AHDLC_TXD ); /*Select the signal for general-purpose output*/ *PADIR(immrval)|=AHDLC_TXD ; *PADAT(immrval) |= AHDLC_TXD ; printf(" CS: 1 ,TXD : 1 \n "); } else if( 3 ==data ) { AHDLC_RX_CS(); /* General-purpose I/O.*/ *PAPAR(immrval) &= (~AHDLC_TXD ); *PAPAR(immrval) |= AHDLC_RXD ; /*Select the signal for general-purpose output*/ *PADIR(immrval)|=AHDLC_TXD ; /*Select the signal for general-purpose intput*/ *PADIR(immrval)&=(~AHDLC_RXD) ; *PADAT(immrval) |= AHDLC_TXD ; printf(" CS: 0 ,TXD : 1,read Rx \n "); k=0; for(j=0;j<100;j++) { taskDelay(sysClkRateGet( )/50); i = (*PADAT(immrval) & AHDLC_RXD); if(i)k++; printf("RXD %x \n" , i ); } printf("1 num %d \n" ,k); } else { init_ports(); printf(" CS: 0 ,TXD : 1 , default set !\n"); }}/****************************************************************************** Function: ahdlcTxdModeSet* Author: JinGu * Description: TXD模式设置,用于控制FPGA TXD脚输出方式* Parameters: mode: 0: FPGA TXD常0; 1: FPGA TXD常1; 2:FPGA 直接输出PPC TXD* Returns: OK or ERROR *****************************************************************************/INT32 ahdlcTxdModeSet(INT8 mode){ switch(mode) { case 0: *REG_LX30T_AHDLC_DATA = 0; *REG_LX30T_AHDLC_CTRL = 1; AHDLC_TX_CS(); printf(" CS: 1 ,TXD : 0 \n "); break; case 1: *REG_LX30T_AHDLC_DATA = 1; *REG_LX30T_AHDLC_CTRL = 1; AHDLC_TX_CS(); printf(" CS: 1 ,TXD : 1 \n "); break; case 2: *REG_LX30T_AHDLC_CTRL = 0; AHDLC_RX_CS(); printf(" CS: 0 ,TXD : 1 , default set !\n"); break; default: return ERROR; } return OK;}UINT8 ahdlcRxdModeRet(void){ UINT8 data; data = (*REG_LX30T_AHDLC_DATA&0x2)>>1; printf("RXD %x \n" , data ); return data;}#endif /* defined(INCLUDE_AHDLC) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -