📄 hdlc100init.c
字号:
HDLCDPLLStatus[cn].DPLLTM = 0; // two clock miss }}////////////////////////////////////////////////////////////////////////////////// GetBaudRate //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////* [1:0] Time constant value for CNT2 *//* 00 = divide by 1 *//* 01 = divide by 16 *//* 10 = divide by 32 *//* [3:2] Time constant value for CNT1 */ /* 00 = divide by 1 *//* 01 = divide by 16 *//* [15:4] Time constant value for CNT0 *//* *//* BRGOUT1 = (MCLK2 or RXC) / (CNT0 + 1) / (16 ** CNT1 ) *//* BRGOUT2 = BRGOUT1 / (1 or 16 or 32 according to CNT2 value of the HBRGTC) */static U32 GetBaudRate(U32 WantedBR){ U32 DIF; // minimal baudrate difference U32 CNT0; // selected counter CNT0 U32 CNT1; // selected counter CNT1 U32 CNT2; // selected counter CNT2 U32 i; // DIF = 0xFFFFFFFF; // start minimal baudrate difference for(i = 0; i < 6; ++i) { U32 scal0; U32 scal1; U32 scal2; U32 dif; U32 br; U32 j; switch(i) { case 0 : scal1 = 1 ; scal2 = 1 ; break; case 1 : scal1 = 1 ; scal2 = 16 ; break; case 2 : scal1 = 1 ; scal2 = 32 ; break; case 3 : scal1 = 16 ; scal2 = 1 ; break; case 4 : scal1 = 16 ; scal2 = 16 ; break; case 5 : scal1 = 16 ; scal2 = 32 ; break; default : ; } scal0 = MCLK2 / WantedBR / scal1 / scal2; for(j = 0; j < 2; j++, scal0++) // { // scal0 = CNT0 + 1 if(scal0 >= 1 && scal0 <= 4096) // CNT0 >= 0 && CNT0 <= 4095 { br = MCLK2 / scal0 / scal1 / scal2; // calculated baudrate if(br > WantedBR) {dif = br - WantedBR;} // baurate differense else {dif = WantedBR - br;} // if(dif < DIF) { // less then minimal dif DIF = dif; // reset minimal difference CNT0 = scal0 - 1; // set counter CNT0 CNT1 = scal1 / 16; // set counter CNT1 CNT2 = scal2 / 16; // set counter CNT2 } } } } // return((CNT0 <<4) | (CNT1<<2) | CNT2 );}////////////////////////////////////////////////////////////////////////////////// Tx Buffer Descriptor generation /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// cn = channel num (0,1)// TxBufLength = transmit buffer length // 0 = default length 0x120// NullPoint = null pointer entry// 0 = circular BD list// else prev[NullPoint]->next = 0void TxBD_init(int cn, int NullPoint){ sHDLCBD * bd; // current buffer descriptor sHDLCBD * start; // start transmit buffer descriptor sHDLCBD * prev; // previous buffer descriptor U32 allocptr; // alloc position U32 alloccnt; // bytes in buffer U32 i; int TxBufLength;// align word boundary ///////////////////////////////////////////////////////// TxBufLength = ((HDLC_TX_BUF_LENGTH + 3) >> 2) << 2;// if(NullPoint <= 0 || NullPoint > HDLC_MAX_TX_DES) { NullPoint = HDLC_MAX_TX_DES; } HDMATXPTR(cn) = // HDMATXPTR gHDLCTxStart[cn] = // Tx BD start position gHDLCTxEnd [cn] = // Tx BD end (U32) sHDLCTxBD[cn] | NonCache; gHDLCTxCount[cn] = 0; // Tx BD count with DMA owner bit// bd = (sHDLCBD *) gHDLCTxStart[cn]; // current buffer descriptor prev = (sHDLCBD *)NULL; // previous buffer descriptor start = bd; // save start buffer descriptor// buffer allocation pointer + non cacheble area allocptr = (U32) HDLCTxAllocBuf[cn] | NonCache; // sizeof of alloc buffer, words alloccnt = HDLC_TX_ALLOC_BUF_SIZE * sizeof(U32); for(i = 0; i < HDLC_MAX_TX_DES; ++i) { if(TxBufLength > alloccnt) { break; // allocation error }// set fields off current buffer descriptor //////////////////////////////////// bd->BufferDataPtr = // frame data pointer (U32) allocptr & // allocation pointer HDLCTxBD_CPU; // clear DMA bit // bd->Reserved = 0x0; bd->StatusLength = TxBufLength; // tx length bd->Next = 0; // pointer to next BD bd->Prev = prev; // pointer to previous BD // if(prev != (sHDLCBD *) NULL) { prev->Next = bd; } if(i == NullPoint) { break; }// prev = bd; // reset previous BD bd++; // move to next allocptr += TxBufLength; // allocation position alloccnt -= TxBufLength; // remain bytes in alloc buffer }// if(NullPoint == HDLC_MAX_TX_DES) {// circular BD list ///////////////////////////////////////////////////////////// bd--; // Last BD bd->Next = start; // pointer to start descriptor start->Prev = bd; }}////////////////////////////////////////////////////////////////////////////////// Rx Buffe Descriptors Init ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////void RxBD_init(int cn) { sHDLCBD * bd; // current BD sHDLCBD * prev; // previous BD sHDLCBD * start; // start buffer descriptor U32 allocptr; // allocation position U32 alloccnt; // remain bytes in allocation buffer U32 i; HDMARXPTR(cn) = // current Rx BD pointer gHDLCRxStart[cn] = // start BD pointer gHDLCRxEnd[cn] = // end BD pointer (U32) sHDLCRxBD[cn] | NonCache;#ifndef USER_AREA gHDLCRxCount[cn] = 0; // Rx BD count #endif // USER_AREA bd = (sHDLCBD *)gHDLCRxStart[cn]; start = bd; prev = (sHDLCBD *)NULL ; allocptr = (U32) HDLCRxAllocBuf[cn] | NonCache; // start allocation position alloccnt = HDLC_RX_ALLOC_BUF_SIZE * sizeof(U32); // bytes in alloc buffer for(i = 0; i < HDLC_MAX_RX_DES; ++i) { if(HDLC_RX_BUF_LENGTH > alloccnt) {// out off alloc buffer //////////////////////////////////////////////////////// break; }// set fields off current buffer descriptor //////////////////////////////////// bd->BufferDataPtr = // buffer data pointer allocptr | // current allocation position HDLCRxBD_DMA; // owner HDMA// bd->Reserved = 0x0; bd->StatusLength = 0x0; // status & length bd->Next = NULL; // next BD bd->Prev = prev; // previous BD if(prev != (sHDLCBD *) NULL) { prev->Next = bd; } prev = bd; // reset previous BD bd++; // move to next buffer descriptor // allocptr += HDLC_RX_BUF_LENGTH; // next alloc address alloccnt -= HDLC_RX_BUF_LENGTH; // remain bytes in alloc buffer }// bd--; // Last BD bd->Next = start; // Assign last buffer descriptor start->Prev = bd; // Assign first buffer descriptor} ////////////////////////////////////////////////////////////////////////////////// This function initiailze the HDLC Block /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////void HDLC_Init(void){ U8 cn; // channel num// clear HDLC Statistics /////////////////////////////////////////////////////// HdlcClrErrReport(); Disable_Int(nGLOBAL_INT); // global disable int // Interrupt Vector Setup ////////////////////////////////////////////////////// SysSetInterrupt(nHDLCTxA_INT, HDLCTxA_isr); // HDLC A Tx ISR SysSetInterrupt(nHDLCRxA_INT, HDLCRxA_isr); // HDLC A Rx ISR SysSetInterrupt(nHDLCTxB_INT, HDLCTxB_isr); // HDLC B Tx ISR SysSetInterrupt(nHDLCRxB_INT, HDLCRxB_isr); // HDLC B Rx ISR// Enable Interrupts /////////////////////////////////////////////////////////// Enable_Int(nHDLCTxA_INT); // enable HDLC A Tx Interrupt Enable_Int(nHDLCRxA_INT); // enable HDLC A Rx Interrupt Enable_Int(nHDLCTxB_INT); // enable HDLC B Tx Interrupt Enable_Int(nHDLCRxB_INT); // enable HDLC B Rx Interrupt for(cn = 0; cn <= 1; ++cn) {//Reset All HDLC block ///////////////////////////////////////////////////////// HCON(cn) |= HCON_TxRS | // Transmit Reset HCON_RxRS | // Receive Reset HCON_DTxRS| // DMA Tx Reset HCON_DRxRS; // DMA Rx Reset// Internal Register Setting for Tx/Rx operation /////////////////////////////// HMODE(cn) = gHMODE; // HDLC mode register HCON(cn) = gHCON; // HDLC control register if(cn == 0) { HINTENA = gHINTENA; } // HDLC int enable register else { HINTENB = gHINTENB; } // Set Baud Rate Generator Counters //////////////////////////////////////////// HBRGTC(cn) = GetBaudRate(gHdlcBaudRate); // Set HDLC Channel Address Registers & Address Mask Register ////////////////// HSAR0(cn) = 0x12345678; // HSAR1(cn) = 0xabcdef01; // HSAR2(cn) = 0xffffffff; // HSAR3(cn) = 0xaaaaaaaa; // HMASK(cn) = 0x00000000; // HMFLR(cn) = HDLC_MAX_FRAME_LENGTH; // maximum frame length register HRBSR(cn) = HDLC_RX_BUF_LENGTH; // // Initialize Buffer Descriptor //////////////////////////////////////////////// TxBD_init(cn,0); // Init Tx Buffer Descriptots RxBD_init(cn); // Init Rx Buffer Descriptots #ifdef USER_AREA HDLCRxUserRead [cn] = HDLCRxUserWrite[cn] = (U32 *) (((U32) HDLCRxUserArea[cn]) | NonCache); HDLCRxUserFirst[cn] = (U32 *) (-1); HDLCRxUserCount[cn] = 0;#endif // USER_AREA HCON(cn) |= (HCON_DRxEN|HCON_RxEN); // HDLCA DMA Rx enable & Rx Enable }// Initialize Global Variables gHDLCRxDone = 0; // no Rx interrupts Enable_Int(nGLOBAL_INT); // enable global interrupt}////////////////////////////////////////////////////////////////////////////////// Send Data ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// cn = channel number // data = data buffer // size = data lengthint HDLCSend(int cn, U8 *data, int size){ sHDLCBD * bd; // current Tx BD U32 * dst; // destination buffer pointer U32 * src; // source pointer int len; // length int cnt; // BD count if(cn < 0 || cn > 1 || data == 0 || size < 6) { // invalid channel number, data buffer return(0); // or data length } bd = (sHDLCBD *) gHDLCTxEnd[cn]; // End Tx BD pointer len = size; // sizeof sended data while(len > 0) { if(bd == 0) { // Null terminating List return(0); // not sufficient space to send data } if(bd->BufferDataPtr & HDLCTxBD_DMA) { // owner DMA return(0); // not sufficient BDs to send data } bd = bd->Next; // move to next BD len -= HDLC_TX_BUF_LENGTH; // remain data bytes }// enough space in buffers ///////////////////////////////////////////////////// cnt = 0; bd = (sHDLCBD *) gHDLCTxEnd[cn]; // restore bd src = (U32 *) data; // source address while(size > 0) { if(bd == 0) { // null terminating list return(0); // } if((bd->BufferDataPtr & HDLCTxBD_DMA)) { // return(0); } if(size <= HDLC_TX_BUF_LENGTH) {// Last Buffer Descriptor ////////////////////////////////////////////////////// bd->Reserved = #ifdef LITTLE HDLCTxBD_Little | // Little-Endian #endif HDLCTxBD_WA0 | // No invalid bytes HDLCTxBD_Last; // Last buffer bd->StatusLength = size; // data length } else {// not last BD ///////////////////////////////////////////////////////////////// bd->Reserved = #ifdef LITTLE HDLCTxBD_Little | // Little-Endian #endif HDLCTxBD_WA0; // No invalid bytes bd->StatusLength = HDLC_TX_BUF_LENGTH; }// copy sended data to destination buffer ////////////////////////////////////// len = ((bd->StatusLength+3)>>2); // length, words dst = (U32 *) bd->BufferDataPtr; // destination pointer while(len-- > 0) { // word copy *dst++ = *src++; } cnt++; // used BD count size -= HDLC_TX_BUF_LENGTH; // remain send data bd->BufferDataPtr |= HDLCTxBD_DMA; // owner DMA bd = bd->Next; // move to next BD } Disable_Int(nGLOBAL_INT); gHDLCTxCount[cn] += cnt; // Tx BD count
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -