📄 hdlcmain.c
字号:
//#define HDLC_BYTE_FILLING #define HDLC_LOOP_DATA_MAX_LEN 1500 int HdlcLoopback(int cn, int lcount, int quiet){// Tx & Rx data buffer static U8 txdata[2][HDLC_LOOP_DATA_MAX_LEN+4]; static U8 rxdata [HDLC_LOOP_DATA_MAX_LEN+4]; U8 txsended[2] = {1, 1}; int tm1en; // timer 1 enable flag TIME tm; // TIME struct U32 startms; // start time, ms U32 curms; // end time, ms U32 status; // Rx status int rlen; // received length int recv; // HDLCRecv return code int more; // more flag U32 rxframes[2]; // receive frame count U32 missed[2]; // missed packets count U32 errminlen[2]; // minimum length error count U32 erraddr[2]; // address error count U32 errlen[2]; // length error count U32 errseq[2]; // sequence error count U32 errdata[2]; // filling data error count U32 errstatus[2]; U32 hash; U32 lcnt[2]; U32 tcnt[2]; // tx packet number U32 rcnt[2]; // rx packet number U32 tbytes[2]; // tx bytes / sec int pos; // buffer posuition int rvl; // return code int i; // channel number U8 it = 0; // console input // Tx frames length int datalen = 120; if(quiet == 0) { Print("\nInput packet count (10000 default)"); lcount = get_number(8, 16); if(lcount == 0) { lcount = 10000; } Print("\nInput packet length (120 default) "); datalen = get_number(8, 16); if(datalen == 0) { datalen = 120; } } if(datalen < 8) { datalen = 8; } if(datalen > HDLC_LOOP_DATA_MAX_LEN) {datalen = HDLC_LOOP_DATA_MAX_LEN;}// rvl = 1;// Print("\nHDLC Channel"); switch(cn) { case 0 : Print(" A"); break; // Channel A test case 1 : Print(" B"); break; // Channel B test case -1 : Print("s A & B"); break; // All channels test default : return(0); } if(gHdlcBaudRate < 500000) { hash = 10; } else { hash = 100; }#ifdef HDLC_BYTE_FILLING Print(" Loopback Test ... ");#else Print(" Loopback Test (W)... ");#endif Print("\n#=%d packets sended.", hash); Print("\nTo break test press [Q].");// tm1en = TimerEnabled(1); // read timer 1 enable flag TimerReset(1); // reset timer 1 TimerInit(1,(ONE_SECOND/TICKS_PER_SECOND)); // init timer 1 TimerStart(1); // start timer 1 GetSysTime(1,& tm); // read start time, convert to ms startms = tm.tm_ms + (tm.tm_sec + tm.tm_min * 60) * 1000;// clear Rx & Tx buffers, enable HDLC channels ///////////////////////////////// Disable_Int(nGLOBAL_INT); // disable global int more = 0; // clear more flag for(i = 0; i < 2; ++i) { txsended[i] = 1; lcnt[i] = lcount; tcnt[i] = 0; // clear transmit packet number rcnt[i] = 0; // clear receive packet number// rxframes[i] = 0; // rx frames missed[i] = 0; // total rx errors errminlen[i] = 0; // minimum length error count erraddr[i] = 0; // address error count errlen[i] = 0; // length error count errseq[i] = 0; // sequence error count errdata[i] = 0; // filling data error count errstatus[i] = 0; if(cn == -1 || i == cn) // { more |= (1 << i); // channel on => set more bit // enable Rx & Tx, DMA Rx & Tx HCON(i) |= HCON_DTxEN | HCON_DRxEN | HCON_TxEN | HCON_RxEN; } } Enable_Int(nGLOBAL_INT); // enable global int while(more) { for(i = 0; i < 2; ++i) {// tx loop ///////////////////////////////////////////////////////////////////// if(i != cn && cn != -1) { continue; } if(tcnt[i] >= lcnt[i]) { if(HDLCTxBD_count(i) == 0) { // all bd transmitted more &= ~(1 << i); // clear more bit if(more ==0) { U32 dms; GetSysTime(1,& tm); dms = curms = tm.tm_ms + tm.tm_sec * 1000; while(curms < dms + 500) { GetSysTime(1,& tm); curms = tm.tm_ms + tm.tm_sec * 1000; } } } } while(tcnt[i] < lcnt[i]) {// channel i tx loop /////////////////////////////////////////////////////////// U8 * data = txdata[i]; if(txsended[i] == 1) {// txdata[i] sended => new filling /////////////////////////////////////////////#ifdef HDLC_BYTE_FILLING// byte filling data[0] = 0xFF; // station address data[1] = 0x0; // data[2] = datalen & 0xFF; // data length (low byte) data[3] = (datalen >> 8)&0xFF; // data length (hight byte) data[4] = tcnt[i] & 0xFF; // transmit number data[5] = (tcnt[i] >> 8)&0xFF; // data[6] = (tcnt[i] >>16)&0xFF; // data[7] = (tcnt[i] >>24)&0xFF; // for(pos = 8; pos < datalen; ++pos) { // fill packet data[pos] = tcnt[i] + pos; } #else// word filling U32 * ptr; // word pointer U32 val; // filling value int wlen; // packet length, words ptr = (U32 *) data; *ptr++ = (datalen << 16)| 0x00FF; // address + datalen *ptr++ = tcnt[i]; // tx sequence number wlen = (datalen + 3) >> 2; // words (include tailing words) val = tcnt[i]; for(pos = 2; pos < wlen; ++pos) { *ptr++ = val++; // words filling }#endif// end txdata[i] filling } if(HDLCSend(i, data, datalen) == 0) { txsended[i] = 0; // data not sended => break; // txdata[i] ready to send } else { tcnt[i]++; // next transmit number txsended[i] = 1; // tx data sended if(tcnt[i] != 0 && (tcnt[i] % hash) == 0) { Print("#"); } } if(kbd_hit()) { it = get_byte(); if(it == 'Q' || it == 'q') { lcnt[0] = tcnt[0]; lcnt[1] = tcnt[1]; } } } // ch i end loop } // if(kbd_hit()) { it = get_byte(); if(it == 'Q' || it == 'q') { lcnt[0] = tcnt[0]; lcnt[1] = tcnt[1]; } } for(i = 0; i < 2; ++i) {// int recvdelta = 128 + 64;// receive looop /////////////////////////////////////////////////////////////// if(i != cn && cn != -1) { continue; } while(1) {#ifndef HDLC_BYTE_FILLING U32 * ptr; U32 val; int wlen;#endif // HDLC_BYTE_FILLING int fillerr; int plen; // int num; //// receive channel i loop ////////////////////////////////////////////////////// rlen = sizeof(rxdata); recv = HDLCRecv(i, &status, rxdata, & rlen); if(recv < 0) { // reveive error rvl = 0; // clear return code break; // break from channel i recv loop } else if(recv == 0) { // no rx data break; } // CRC Error (CE), Non-octet Aligned Frame (NO), Overrun (OV), Rx Abort (ABT)// Frame Length Violation (FLV) if( (status & (HDLCRxBD_CRC | HDLCRxBD_NO | HDLCRxBD_OV | HDLCRxBD_ABT | HDLCRxBD_FLV) ) != 0 ) { rvl = 0; missed[i] += 1; // channel error count errstatus[i] += 1; // status error count } rxframes[i]++; // total rx frames if(rlen < 8) {// minimal length error //////////////////////////////////////////////////////// rvl = 0; if(quiet == 0) { Print("\nRx Frame minimum length error. Length = %d\n", rlen); } missed[i] += 1; // channel error count errminlen[i] += 1; // channel i minimal length error count continue; } if(rxdata[0] != 0xFF && rxdata[1] != 0x00) {// address error /////////////////////////////////////////////////////////////// rvl = 0; if(quiet == 0) { Print("\nRx Frame address error.Address [0x%02x%02x],Length=[%d],Wait Num=[%d]", rxdata[0], rxdata[1], rlen, rcnt[i] ); Print("\nData"); for(pos = 0; pos < 8; ++pos) { Print(" %02x", rxdata[pos]); } } missed[i] += 1; // channel i error count erraddr[i] += 1; // channel i address error count continue; } // read frame length from frame plen = (U32) rxdata[2] | ((U32) rxdata[3] << 8); if(plen + 2 != rlen || rlen != datalen + 2) {// frame length error ////////////////////////////////////////////////////////// if(quiet == 0) { Print("\nRx Frame length error. Frame length=%d, writed in packet=%d", rlen , plen ); } rvl = 0; missed[i] += 1; // channel i error count errlen[i] += 1; // channel i frame length error count continue; }#ifdef HDLC_BYTE_FILLING num = (U32) rxdata[4] | // lo byte ((U32) rxdata[5] << 8) | // lo mi byte ((U32) rxdata[6] << 16) | // hi ((U32) rxdata[7] << 24); #else num = *((U32 *) (rxdata + 4));#endif // HDLC_BYTE_FILLING if(rcnt[i] != num) {// sequence number error /////////////////////////////////////////////////////// if(quiet == 0) { Print("\nRx Sequence number error (wait =%d, rx = %d)\n", rcnt[i] , num ); } rvl = 0; rcnt[i] = num + 1; // reset wait rx num missed[i] += 1; // missed packets count errseq[i] += 1; // channel i sequence error count continue; }// wait packet number equal received packet number /////////////////////////////// => check packet filling fillerr = 0;#ifdef HDLC_BYTE_FILLING for(pos = 8; pos < rlen - 2; ++pos) // check packet filling { if(rxdata[pos] != (U8)(rcnt[i] + pos)) { fillerr = 1; break; } }#else wlen = (rlen - 2) >> 2; // length full words ptr = (U32 *)(rxdata + 8); // filling data pointer val = rcnt[i]; for(pos = 2; pos < wlen; ++pos) { if(*ptr++ != val++) { fillerr = 1; break; } } if(fillerr == 0 && ((rlen - 2) & 0x3) != 0) { U32 mask; switch((rlen - 2) & 0x3) { case 1 : mask = 0x000000FF; break; case 2 : mask = 0x0000FFFF; break; case 3 : mask = 0x00FFFFFF; break; default : mask = 0x00000000; break; } if( (*ptr & mask) != (val & mask) ) { fillerr = 1; } }#endif // HDLC_BYTE_FILLING if(fillerr == 1) { if(quiet == 0) { Print("\nRx frame filling error. Position=%d", pos); } rvl = 0; // clear return code missed[i] += 1; // channel i rx error count errdata[i] += 1; // channel i data filling error count if(quiet == 0) { Print("\n"); for(pos = 0; pos < rlen; ++pos) { Print("%02x ", rxdata[pos]); if(((pos + 1) % 16) == 0) { Print("\n"); } } Print("\n"); { break; } } } // next wait frame ///////////////////////////////////////////////////////////// rcnt[i]++; if(kbd_hit()) { it = get_byte(); if(it == 'Q' || it == 'q') { lcnt[0] = tcnt[0]; lcnt[1] = tcnt[1]; } }// end of recv chan i } // end of recv loop } } Disable_Int(nGLOBAL_INT); // disable global interrupt for(i = 0; i < 2; ++i) { if(i == cn || cn == -1) { HCON(i) &= ~( HCON_DTxEN | HCON_TxEN | // disable DMA Tx HCON_DRxEN | HCON_RxEN // disable DMA Rx );//#ifdef HDLC_RESET Print("\nResetting HDLC %c",(i?'B':'A')); HDLCRx_reset(i); // reset Rx HDLCTx_reset(i); // reset Tx#endif // HDLC_RESET } }//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -