📄 hdlclib.c
字号:
/*************************************************************************/
/* */
/* FILE NAME VERSION */
/* */
/* hdlclib.c KS32C5000(A) : version 1.0 */
/* */
/* COMPONENT */
/* */
/* DESCRIPTION */
/* */
/* HDLC(high level data link control) function define. */
/* */
/* AUTHOR */
/* */
/* */
/* DATA STRUCTURES */
/* */
/* */
/* FUNCTIONS */
/* */
/* */
/* DEPENDENCIES */
/* */
/* */
/* HISTORY */
/* */
/* NAME DATE REMARKS */
/* */
/* hbahn 09-15-1998 Created initial version 1.0 */
/* */
/*************************************************************************/
#include "sysconf.h"
#include "snds.h"
#include "uart.h"
#include "pollio.h"
#include "timer.h"
#include "isr.h"
#include "hdlc.h"
// Global variable for HDLC Channel A test
extern volatile U32 gHCon0 ;
extern volatile U32 gHCon1 ;
extern volatile U32 gHintEn ;
// Global variable for HDLC Tx/Rx Status report
extern pHdlcTxStatus gHdlcTxStatus[HDLCPORTNUM] ;
extern pHdlcRxStatus gHdlcRxStatus[HDLCPORTNUM] ;
extern pHdlcDPLLStatus gHdlcDPLLStatus[HDLCPORTNUM] ;
// Global variable for buffer descriptor
extern volatile U32 gCTxBDPtr[HDLCPORTNUM], pCTxBDPtr[HDLCPORTNUM] ;
extern volatile U32 gCRxBDPtr[HDLCPORTNUM], pCRxBDPtr[HDLCPORTNUM] ;
/*
* Function : Transmit_Multi_Frame
* Description : Transmit HDLC frame
*/
void Transmit_Multi_Frame(void)
{
sHDLCFrame FrameBuffer ;
int i, loop=1 ;
int Size = 30 ;
U32 channel ;
U8 select ;
Print("\n\n >> Select transfer channel ('A' or 'B') ? ") ;
select = get_byte() ;
switch (select) {
case 'A' : case 'a' : channel = HDLCA ; break ;
case 'B' : case 'b' : channel = HDLCB ; break ;
default : Print("\nInvalid HDLC channel selected ....") ;
break ;
}
Print("\n\n >> HDLC channel %c Multiple transfer \n",to_upper(select)) ;
// Step 1. Set destination address fields
FrameBuffer.Header.Address[0] = 0x12 ;
FrameBuffer.Header.Address[1] = 0x34 ;
FrameBuffer.Header.Address[2] = 0x56 ;
FrameBuffer.Header.Address[3] = 0x78 ;
// Step 2. Set Control field
FrameBuffer.Header.Control[0] = 0xff ;
while(1) {
// do until key stroke
if (UARTSTAT0 & USTAT_RCV_READY) break ;
// Step 3. Set HDLC Frame Data
for (i=0;i<Size-(sizeof(sHDLCHeader));i++)
FrameBuffer.Information[i] = (U8)(i & 0xFF) ;
// Step 4. Send HDLC frame
if (SendHdlcFrame(channel,(U8 *)&FrameBuffer,Size) ) {
if (loop++ == 5) {
// Calcurate Size
loop = 1 ;
if ( Size <= (sizeof(sHDLCFrame)-(sizeof(sHDLCHeader))) )
Size ++ ;
else Size = 30 ; // test
}
}
}
get_byte() ;
}
/*
* Function : Transmit_Frame
* Description : Transmit HDLC frame
*/
void Transmit_Frame(void)
{
sHDLCFrame FrameBuffer ;
int i ;
int Size = 1500 ; // Max size
U8 TransferFrame ;
U32 channel ;
U8 select ;
Print("\n\n >> Select transfer channel ('A' or 'B') ? ") ;
select = get_byte() ;
switch (select) {
case 'A' : case 'a' : channel = HDLCA ; break ;
case 'B' : case 'b' : channel = HDLCB ; break ;
default : Print("\nInvalid HDLC channel selected ....") ;
break ;
}
Print("\n\n >> HDLC channel %c Single transfer \n",to_upper(select)) ;
// Step 1. Set destination address fields
FrameBuffer.Header.Address[0] = 0x12 ;
FrameBuffer.Header.Address[1] = 0x34 ;
FrameBuffer.Header.Address[2] = 0x45 ;
FrameBuffer.Header.Address[3] = 0x67 ;
// Step 2. Set Control field
FrameBuffer.Header.Control[0] = 0xff ;
// Step 3. Set HDLC Frame Data
for (i=0 ; i< (Size-(sizeof(sHDLCHeader))) ; i++)
FrameBuffer.Information[i] = (U8)(i & 0xFF) ;
do {
Print("\r $$ Select Transmit(T) or Quit(Q) ? ") ;
TransferFrame = get_byte() ;
if (Size < HDLC_MTU) Size++ ;
else Size = 30 ;
if ( (TransferFrame == 'T') || (TransferFrame == 't') )
// Step 4. Send HDLC frame
if (!SendHdlcFrame(channel,(U8 *)&FrameBuffer,Size) )
Print("\n HDLC %d Send error",channel) ;
} while ( (TransferFrame != 'Q') && (TransferFrame != 'q') ) ;
}
/*
* Function : HdlcFrameRx
* Description : Test program for HDLC frame Receive
*/
void HdlcFrameRx(void)
{
U32 channel ;
U8 select ;
Print("\n\n Select receive channel ('A' or 'B') ? ") ;
select = get_byte() ;
switch (select) {
case 'A' : case 'a' : channel = HDLCA ; break ;
case 'B' : case 'b' : channel = HDLCB ; break ;
default : Print("\nInvalid HDLC channel selected ....") ;
break ;
}
Print("\n\n >> HDLC channel %c receive frame\n",to_upper(select)) ;
Print("\r >> Press any key to quit receive ...") ;
while(1) {
// do until key stroke
if (UARTSTAT0 & USTAT_RCV_READY) break ;
ReceiveHdlcFrame(channel) ;
}
get_byte() ;
Print("\n Finished ") ;
}
/*
* Function : ReceiveAndViewHdlcFrame
* Description : Receive and view frame one by one
*/
void ReceiveAndViewHdlcFrame(void)
{
sBufferDescriptor *pRxBDPtr ;
U32 CRxBDPtr ;
U32 *DataBuffer ;
U32 Length ;
U32 Status ;
U32 channel ;
U8 select ;
Print("\n\n Select receive channel ('A' or 'B') ? ") ;
select = get_byte() ;
switch (select) {
case 'A' : case 'a' : channel = HDLCA ; break ;
case 'B' : case 'b' : channel = HDLCB ; break ;
default : Print("\nInvalid HDLC channel selected ....") ;
break ;
}
Print("\n\n >> HDLC channel %c receive \n",to_upper(select)) ;
while(1) {
// do until key stroke
if (UARTSTAT0 & USTAT_RCV_READY) break ;
// Step 1. Get current frame buffer pointer
CRxBDPtr = (U32)gCRxBDPtr[channel] ;
do {
// Step 2. Get frame buffer pointer for process
pRxBDPtr = (sBufferDescriptor *)pCRxBDPtr[channel] ;
// Step 3. Check Ownership is CPU or not
if ( !((U32)(pRxBDPtr->BufferDataPtr) & BOwnership_DMA) ) {
// Step 4. If ownership is CPU, then receive frame is exist
// So, get this frame to process
DataBuffer = (U32 *)pRxBDPtr->BufferDataPtr ;
Length = pRxBDPtr->LengthField ;
Status = pRxBDPtr->StatusField ;
if ( !( Status & (RxFERR | DRxABT) ) )
PrintHdlcRxFrame((U8 *)DataBuffer,Length);
}
else break ;
// Step 5. Change owner to DMA
(pRxBDPtr->BufferDataPtr) |= BOwnership_DMA;
pRxBDPtr->LengthField = (U32)0x0;
pRxBDPtr->StatusField = (U32)0x0;
// Step 6. check all descriptor is used, then enable HDLC receive
if ( gCRxBDPtr[channel] == pCRxBDPtr[channel] )
HDLC_Rx_init(channel) ;
// Step 7. Get Next Frame Descriptor pointer to process
pCRxBDPtr[channel] = (U32)(pRxBDPtr->NextBufferDescriptor) ;
} while (CRxBDPtr != pCRxBDPtr[channel]);
}
get_byte() ;
Print("\n Finished !!! ") ;
}
/*
* Function : PrintHdlcRxFrame
* Description : Print HDLC Received Data
*/
void PrintHdlcRxFrame(U8 *pFramePtr, U32 Length)
{
U8 *pFrameData;
U32 i,ColumnSize ;
pFrameData = (U8 *)pFramePtr ;
Print("\n >> HDLC Frame Base : %08",pFramePtr) ;
Print("\n >> HDLC Frame Length : %d",Length) ;
Print("\r -- Address Field : ") ;
for(i=0; i < 4; i++) Print("%02x ", *pFrameData++);
Print("\r -- Control Field : %02x",*pFrameData++);
Print("\r -- HDLC Frame Data : ") ;
ColumnSize = Length - sizeof(sHDLCHeader) ;
do {
for(i=0; i < 16 ; i++)
{
Print("%02x ", *pFrameData++);
if (--ColumnSize == 0) break ;
}
Print("\r%22c",' ') ;
} while(ColumnSize) ;
}
/*
* Function : HdlcInternalLoopback
* Description : HDLC Internal Loopback test program
*/
int HdlcInternalLoopback(void)
{
U32 reg_value ;
U32 channel ;
int return_value = 0 ;
Print("\n\n >> HDLC channel A Internal Loopback Test ... ") ;
channel = HDLCA ;
reg_value = HCON1(channel) ;
HCON1(channel) = gHCon1 | DF_NRZ | TxCLK_BRG1 | RxCLK_BRG1 | TxLOOP ;
if ( !HdlcLoopback(channel, 50) ) return_value = 0 ;
else return_value = 1 ;
HCON1(channel) = reg_value ;
Print("\n >> HDLC channel B Internal Loopback Test ... ") ;
channel = HDLCB ;
reg_value = HCON1(channel) ;
HCON1(channel) = gHCon1 | DF_NRZ | TxCLK_BRG1 | RxCLK_BRG1 | TxLOOP ;
if ( !HdlcLoopback(channel, 50) ) return_value = 0 ;
else return_value = 1 ;
HCON1(channel) = reg_value ;
Print("\n\n") ;
return return_value ;
}
/*
* Function : HdlcExternalLoopback
* Description : HDLC External Loopback test program
*/
void HdlcExternalLoopback(U32 channel)
{
U32 reg_value ;
reg_value = HCON1(channel) ;
HCON1(channel) = gHCon1 | DF_NRZ | TxCLK_BRG1 | RxCLK_BRG1 ;
HdlcLoopback(channel, 50) ;
HCON1(channel) = reg_value ;
Print("\n\n") ;
}
/*
* Function : HdlcExternalLoopback
* Description : Repeated HDLC External Loopback test program
*/
void RepHdlcLoopback(void)
{
int i,lcnt,fail;
lcnt = fail = 0;
Print("\rEnter the repeat counter value for HDLC loopback!\r");
Print("$_ "); lcnt = get_num();
Print("\r$ Loopback counte value is %d\r",lcnt);
for(i=0; i < lcnt ; i++)
{
SyscfgInit(i%3); /* Cache mode will be changed */
if ( !HdlcInternalLoopback() )
{
Print("\n $$$ HDLC Test%d FAIL at %s Mode!!! ",i,PrintCM(i%3)) ;
fail++;
Print("\r> Up to now, %d times FAIL occurred\r",fail);
}
else {
Print("\n $$$ HDLC Test%d PASS at %s Mode!!!\r ",i,PrintCM(i%3)) ;
}
}
Print("\rHDLC Loopback test Finished!\r");
}
char *PrintCM(int m)
{
char *mode[100];
switch(m) {
case 0 : *mode = "4K CACHE";
break;
case 1 : *mode = "8K CACHE";
break;
case 2 : *mode = "CACHE OFF";
break;
}
return(*mode);
}
/*
* Function : HdlcLoopback
* Description : HDLC Internal Loopback test program
*/
int HdlcLoopback(U32 channel, int cnt)
{
sBufferDescriptor *pRxBDPtr ;
sHDLCFrame FrameBuffer ;
U32 CRxBDPtr ;
U8 *DataBuffer ;
U32 Length, Size = 1500 ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -