📄 hdlc100init.c
字号:
Enable_Int(nGLOBAL_INT); gHDLCTxEnd[cn] = (U32) bd; // reset end pointer // set Tx enable, DMA Tx enable bits /////////////////////////////////////////// HCON (cn) |= HCON_TxEN | HCON_DTxEN; // Tx enable & DMA Tx enable HINTEN(cn) |= HINTEN_DTxNOIE; // enable not owner int return(1);}////////////////////////////////////////////////////////////////////////////////// HDLC Channel A Tx ISR ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////#ifdef HDLC_TX_ISR_DEBUG#define HDLCTx_isr_debug(ch) put_byte(ch)#else#define HDLCTx_isr_debug(ch)#endif // HDLC_TX_ISR_DEBUGvoid HDLCTx_isr(int cn){ U32 stat; // HDLC status register U32 clear; // HDLC status register clear bits stat = HSTAT(cn); // read status register clear = 0; // no cleared registers #ifdef HDLC_TX_ISR_DEBUG HDLCTxStatus[cn].TxISR++;#endif // HDLC_TX_ISR_DEBUG HDLCTx_isr_debug('T'); // T = Tx ISR if(stat & HSTAT_DTxFD) {////////////////////////////////////////////////////////////////////////////////// Tx Frame Done /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// sHDLCBD * bd; // U32 * data; // int i; HDLCTx_isr_debug('D');// HDLC DMA Frame Done ///////////////////////////////////////////////////////// HDLCTxStatus[cn].DMATxFD++; // Tx Frame Done clear |= HSTAT_DTxFD; // Clear DMA Tx Done Bit// Check Tx Ownership in all Tx BD ///////////////////////////////////////////// bd = (sHDLCBD *) gHDLCTxStart[cn]; // start Tx buffer descriptor for(i = 0; i < HDLC_MAX_TX_DES; ++i) { data = & bd->BufferDataPtr; // pointer to buffer data & owner bit if((*data & HDLCTxBD_DMA)) { // owner DMA not CPU break; // break } if((U32) bd == HDMATXPTR(cn)) { break; } if(bd->Next == 0) { Print("\nHDLCTxA_isr null next pointer"); break; // circular buffers } data = & bd->Reserved; // pointer to reserved field if((*data & HDLCTxBD_Last)) {// last buffer in frame => check Tx Complete bit /////////////////////////////// data = & bd->StatusLength; if((*data & HDLCTxBD_TxComp) == 0) { HDLCTxStatus[cn].TxLBDNC++; } } bd->Reserved = 0; bd->StatusLength = 0; bd = bd->Next; // move to next BD gHDLCTxCount[cn]--; // Tx Queue descriptors gHDLCTxStart[cn] = (U32) bd; // reset current Tx BD } }//////////////////////////////////////////////////////////////////////////////// // Check and clear other Tx bits /////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// if(stat & HSTAT_TxFC) {// [4] Tx frame complete (TxFC) //////////////////////////////////////////////// HDLCTxStatus[cn].TxFC++; // Tx Complete clear |= HSTAT_TxFC; // clear Tx Frame complete bit HDLCTx_isr_debug('C'); // } if(stat & HSTAT_TxFA) {// [5] Tx FIFO available (TxFA) /////////////////////////////////////////////// HDLCTxStatus[cn].TxFA++; /* during the DMA operation this bit allvais zero */ HDLCTx_isr_debug('F'); } if(stat & HSTAT_TxSCTS) {// [7] Tx stored clear-to-send (TxSCTS) //////////////////////////////////////// HDLCTxStatus[cn].TxSCTS++; clear |= HSTAT_TxSCTS; // clear stored clear-to-send HDLCTx_isr_debug('S');// if((stat & HSTAT_TxCTS))// {//// nCTS low ////////////////////////////////////////////////////////////////////// if((HCON(cn) & HCON_DTxEN) == 0)// {// HDLCTx_isr_debug('E');// HCON(cn) |= HCON_DTxEN;// }// } // else// {//// nSTS high ///////////////////////////////////////////////////////////////////// HDLCTx_isr_debug('R');// } } if(stat & HSTAT_TxU) {// [8] Tx underrun (TxU) /////////////////////////////////////////////////////// HDLCTxStatus[cn].TxU++; // Tx underrun statistics clear |= HSTAT_TxU; // clear Tx Underrun bit HDLCTx_isr_debug('U'); } if(stat & HSTAT_DTxABT) {// DMA Tx abbort (due Tx underrun, CTS lost) /////////////////////////////////// HDLCTxStatus[cn].DMATxABT++; // DMA Tx Abort statistics clear |= HSTAT_DTxABT; // clear DMA Tx Abort bit // DMA Transmit enable bit DTxEN (in HCON) cleared HDLCTx_isr_debug('A');// if((HCON(cn) & HCON_DTxEN) == 0)// {//#ifdef HDLC_TX_ISR_DEBUG// HDLCTx_isr_debug('a');//#endif // HCON(cn) |= HCON_DTxEN;// } } if(stat & HSTAT_DTxNL) {// [28] DMA Tx null list interrupt ///////////////////////////////////////////// HDLCTxStatus[cn].DMATxNL++; // DMA Tx Null List statistics clear |= HSTAT_DTxNL; // clear DMA Tx Null List bit HDLCTx_isr_debug('N'); } if(stat & HSTAT_DTxNO) {// [29] DMA Tx not owner (DTxNO) /////////////////////////////////////////////// HDLCTxStatus[cn].DMATxNO++; // DMA Tx not owner statistics clear |= HSTAT_DTxNO; // clear DMA Tx Not Owner bit // DMA Transmit enable bit DTxEN (in HCON) cleared HDLCTx_isr_debug('O'); HINTEN(cn) &= ~HINTEN_DTxNOIE; }// clear status bits /////////////////////////////////////////////////////////// HSTAT(cn) = clear; }////////////////////////////////////////////////////////////////////////////////// HDLC Channel A Tx ISR ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////void HDLCTxA_isr(void){ HDLCTx_isr(0);}////////////////////////////////////////////////////////////////////////////////// HDLC Channel B Tx ISR ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////void HDLCTxB_isr(void){ HDLCTx_isr(1);}////////////////////////////////////////////////////////////////////////////////// clear Rx buffers ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////int HDLCRx_reset(int cn){ sHDLCBD * bd; // descriptor pointer U32 intbit; // HDLC channel Rx Int bit int i; // decriptor index if(cn < 0 || cn > 1) { // invalid channel return(0); // number } intbit = (cn ? nHDLCRxB_INT : nHDLCRxA_INT); Disable_Int(intbit); // disable HDLC Rx Int Clear_PendingBit(intbit); // clear HDLC Rx pending bit HCON(cn) &= ~(HCON_RxEN | HCON_DRxEN); // disable Rx & DMA Rx HCON(cn) |= (HCON_RxRS | HCON_DRxRS); // reset Rx & DMA Rx// #ifdef USER_AREA HDLCRxUserRead [cn] = // start position HDLCRxUserWrite[cn] = // end position (U32 *) ((U32) HDLCRxUserArea[cn] | NonCache); HDLCRxUserFirst[cn] = (U32 *) (-1); // first buffer position HDLCRxUserCount[cn] = 0; // bytes count#endif // USER_AREA// #ifdef USER_AREA bd = (sHDLCBD *) gHDLCRxEnd[cn]; // moved by ISR #else bd = (sHDLCBD *) gHDLCRxStart[cn]; // moved by Recv #endif // USER_AREA for(i = 0; i < HDLC_MAX_RX_DES; ++i) { if((bd->BufferDataPtr & HDLCTxBD_DMA) != 0) {// descriptor owner DMA (not CPU) => break ///////////////////////////////////// break; } bd->BufferDataPtr |= HDLCTxBD_DMA; // set DMA bit bd->Reserved = 0; // clear reserved field bd->StatusLength = 0; // clear status length field if(bd->Next == 0) { // null terminating list break; } bd = bd->Next; // move to next descriptor }// HDMARXPTR(cn) = (U32) bd; // set current BD register gHDLCRxStart[cn]= (U32) bd; // set start Rx BD gHDLCRxEnd[cn] = (U32) bd; // set end Rx BD #ifndef USER_AREA gHDLCRxCount[cn]= 0; // Rx BD count #endif // not def USER_AREA HSAR0(cn) = 0x12345678; // addr 0 reg HSAR1(cn) = 0xabcdef01; // addr 1 reg HSAR2(cn) = 0xffffffff; // addr 2 reg HSAR3(cn) = 0xaaaaaaaa; // addr 3 reg HMASK(cn) = 0x00000000; // addr mask reg HMFLR(cn) = HDLC_MAX_FRAME_LENGTH; // maximum frame length register HRBSR(cn) = HDLC_RX_BUF_LENGTH; // recv buffer size HCON(cn) = gHCON | HCON_DRxEN | HCON_RxEN; // restore control register HINTEN(cn) = (cn ? gHINTENB : gHINTENA); // restore int reg Enable_Int(intbit); // enable rx int return(1);}////////////////////////////////////////////////////////////////////////////////// return count not transmitted Tx BD //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////int HDLCTxBD_count(int cn){ if(cn < 0 || cn > 1) { // invalid channel return(0); // number } return(gHDLCTxCount[cn]);}////////////////////////////////////////////////////////////////////////////////// clear Tx buffer descriptosr /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////int HDLCTx_reset(int cn){ sHDLCBD * bd; // descriptor pointer U32 intbit; int i; // descriptor index if(cn < 0 || cn > 1) { // invalid channel number return(0); // } intbit = (cn ? nHDLCTxB_INT : nHDLCTxA_INT); Disable_Int(intbit); Clear_PendingBit(intbit); bd = (sHDLCBD *) HDMATXPTR(cn); // current Tx bd HCON(cn) &= ~(HCON_TxEN | HCON_DTxEN); // disable Tx & DMA Tx HCON(cn) |= (HCON_TxRS | HCON_DTxRS); // reset Tx & DMA Tx // Check Tx Ownership in all Tx BD ///////////////////////////////////////////// for(i = 0; i < HDLC_MAX_TX_DES; ++i) { if((bd->BufferDataPtr & HDLCTxBD_DMA) == 0) { // owner CPU => break ////////////////////////////////////////////////////////// break; } bd->BufferDataPtr &= ~HDLCTxBD_DMA; // Owner CPU bd->Reserved = 0; // clear reserved field bd->StatusLength = 0; // clear status length field if(bd->Next == 0) { Print("\nHDLC Tx BD null next pointer"); break; // circular buffers } bd = bd->Next; // move to next BD } gHDLCTxStart[cn] = (U32) bd; // set start Tx BD gHDLCTxEnd[cn] = (U32) bd; // set end Tx BD gHDLCTxCount[cn] = 0; // Tx BD count HDMATXPTR(cn) = (U32) bd; // set current Tx BD pointer HCON(cn) = gHCON; // restore HCON HINTEN(cn) = (cn ? gHINTENB:gHINTENA); // restore HINTEN Enable_Int(intbit); return(1);}////////////////////////////////////////////////////////////////////////////////// save Rx buffer //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////#ifdef USER_AREAstatic U32 GetRxBDData(int cn, U32 buf, U32 status, int len){ U32 * data; // U32 * ptr; // write pointer U32 * start; // queue start pointer U32 * end; // queue end pointer int dcnt = 0; // HDLCRxUserCount increment int wlen; wlen = (len + 3) / 4; if(wlen + 1 + HDLCRxUserCount[cn] > HDLC_USER_AREA_SIZE ) { Print("\nGetRxBDData buffer full %d %d", len, HDLCRxUserCount[cn]); return(0); } // // start = (U32 *) HDLCRxUserArea [cn] /*| NonCache*/; // start pointer // end = start + HDLC_USER_AREA_SIZE; // end pointer // ptr = (U32 *) HDLCRxUserWrite[cn] /*| NonCache*/; // write pointer start = (U32 *) ((U32)HDLCRxUserArea [cn] | NonCache); ptr = (U32 *) ((U32)HDLCRxUserWrite[cn] | NonCache); end = start + HDLC_USER_AREA_SIZE; if(ptr >= end) { ptr = start; }// if(status & HDLCRxBD_F) // [22] First In Frame (F) { U32 * fptr;////////////////////////////////////////////////////////////////////////////////// first buffer in frame => write to queue preample, status, length //////////////////////////////////////////////////////////////////////////////////////////// fptr = (U32 *) ((U32) HDLCRxUserFirst[cn] | NonCache); if(fptr != (U32 *) -1) { if(fptr >= end) { fptr = start; }// rotate to queue start *fptr |= ((U32)HDLCRxBD_L << 16); } if(ptr >= end) { ptr = start; } // rotate to begin queue if((status & HDLCRxBD_L) == 0) { // last bit not set => save first pointer ////////////////////////////////////// HDLCRxUserFirst[cn] = ptr; // set first buffer pointer } else {// first and last frame buffer ///////////////////////////////////////////////// HDLCRxUserFirst[cn] = (U32 *) -1; // clear first pointer } *ptr = ((status & 0xFFFF) << 16) | (len & 0xFFFF); if(++ptr >= end) { ptr = start; } // rotate to queue start dcnt += 1; // writed words count } else {////////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -