📄 hdlcinit.c
字号:
/*************************************************************************/
/* */
/* FILE NAME VERSION */
/* */
/* hdlcinit.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 */
/* hbahn 06-05-1999 Modified version 1.0 */
/* */
/*************************************************************************/
#include <stdarg.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include "snds.h"
#include "sysconf.h"
#include "uart.h"
#include "pollio.h"
#include "timer.h"
#include "isr.h"
#include "hdlc.h"
// Global variable for HDLC Channel A test
volatile U32 gHCon0 = BRGEN | TxRTS | TxDTR ;
#ifdef LITTLE
volatile U32 gHCon1 = F4WM | TxLittle | RxLittle | DTxMAINC | DRxMAINC | \
DRxSTOPTC | BRGCLK_MCLK | DPLLCLK_MCLK ;
#else
volatile U32 gHCon1 = F4WM | DTxMAINC | DRxMAINC | DRxSTOPTC | BRGCLK_MCLK |\
DPLLCLK_MCLK ;
#endif
volatile U32 gHintEn= HDLCIE | TxIE | RxIE ;
// Global variable for HDLC Tx/Rx Status report
pHdlcTxStatus gHdlcTxStatus[HDLCPORTNUM] ;
pHdlcRxStatus gHdlcRxStatus[HDLCPORTNUM] ;
pHdlcDPLLStatus gHdlcDPLLStatus[HDLCPORTNUM] ;
// HDLC Device entry point
HDLC_Device_Entry HDLC_Dev[HDLCPORTNUM] ;
// HDLC Frame Buffer Descriptor and Data Buffer
sBufferDescriptor TxBDABase[HDLCPORTNUM][MaxTxBufferDescriptor] ;
sBufferDescriptor RxBDABase[HDLCPORTNUM][MaxRxBufferDescriptor] ;
sHDLCFrame TxBABase[HDLCPORTNUM][MaxTxBufferDescriptor] ;
sHDLCFrame RxBABase[HDLCPORTNUM][MaxRxBufferDescriptor] ;
// Global variable for buffer descriptor
volatile U32 gCTxBDPtr[HDLCPORTNUM], pCTxBDPtr[HDLCPORTNUM] ;
volatile U32 gCRxBDPtr[HDLCPORTNUM], pCRxBDPtr[HDLCPORTNUM] ;
// Global variable for transmit frame by interrupt mode
volatile U8 *ModeInt_TxDataBuffer[HDLCPORTNUM] ;
volatile U32 ModeInt_TxDataSize[HDLCPORTNUM] ;
volatile U32 *ModeInt_RxDataBuffer[HDLCPORTNUM] ;
volatile U32 ModeInt_RxDataSize[HDLCPORTNUM] ;
volatile U8 *HDLCTXFIFOT, *HDLCTXFIFOC ;
U8 *TempBuf[1520] ;
/*
* Function : HdlcInitialize
* Description : HDLC controller initialize
*/
void HdlcInitialize(void)
{
HDLC_Device_Entry *Dev_entry[HDLCPORTNUM] ;
int channel;
Disable_Int(nHDLCA_INT);
Disable_Int(nHDLCB_INT);
// Step 1. Set HDLC channel A initialize parameter
Dev_entry[HDLCA] = (HDLC_Device_Entry *)&HDLC_Dev[HDLCA] ;
Dev_entry[HDLCA]->HDLC_Port = HDLCA ;
Dev_entry[HDLCA]->HDLC_Baud = 64000 ;
Dev_entry[HDLCA]->HDLC_Data_format = DF_NRZ ;
Dev_entry[HDLCA]->HDLC_Tx_Mode = MODE_DMA ;
Dev_entry[HDLCA]->HDLC_Rx_Mode = MODE_DMA ;
Dev_entry[HDLCA]->HDLC_Tx_Output_Clk = TxOCLK_BRG1 ;
Dev_entry[HDLCA]->HDLC_Tx_Clk = TxCLK_BRG1 ;
Dev_entry[HDLCA]->HDLC_Rx_Clk = RxCLK_RXC ;
Dev_entry[HDLCA]->HDLC_Station_Addr = HDLC_STATION_ADDR ;
// Tx clock polarity, only for KS32C5000A,
// when set 0 the polarity is same as KS32C5000
Dev_entry[HDLCA]->HDLC_Tx_Clk_Pos = TxCNEG ;
// Rx clock polarity, only for KS32C5000A,
// when set 1 the polarity is same as KS32C5000
Dev_entry[HDLCA]->HDLC_Rx_Clk_Pos = RxCPOS ;
// Step 2. Set HDLC channel B initialize parameter
Dev_entry[HDLCB] = (HDLC_Device_Entry *)&HDLC_Dev[HDLCB] ;
Dev_entry[HDLCB]->HDLC_Port = HDLCB ;
Dev_entry[HDLCB]->HDLC_Baud = 64000 ;
Dev_entry[HDLCB]->HDLC_Data_format = DF_NRZ ;
Dev_entry[HDLCB]->HDLC_Tx_Mode = MODE_DMA ;
Dev_entry[HDLCB]->HDLC_Rx_Mode = MODE_DMA ;
Dev_entry[HDLCB]->HDLC_Tx_Output_Clk = TxOCLK_BRG1 ;
Dev_entry[HDLCB]->HDLC_Tx_Clk = TxCLK_BRG1 ;
Dev_entry[HDLCB]->HDLC_Rx_Clk = RxCLK_RXC ;
Dev_entry[HDLCB]->HDLC_Station_Addr = HDLC_STATION_ADDR ;
// Tx clock polarity, only for KS32C5000A,
// when set 0 the polarity is same as KS32C5000
Dev_entry[HDLCB]->HDLC_Tx_Clk_Pos = TxCNEG ;
// Rx clock polarity, only for KS32C5000A,
// when set 1 the polarity is same as KS32C5000
Dev_entry[HDLCB]->HDLC_Rx_Clk_Pos = RxCPOS ;
// Step 3. Initialize each HDLC port
for(channel=HDLCA ; channel<=HDLCB ; channel++)
{
if ( !HdlcPortInit(Dev_entry[channel]) )
Print("\n HDLC channel [%d] initialize error",channel) ;
}
// Step 4. Setup Interrupt for HDLC
SysSetInterrupt(nHDLCA_INT, HDLCA_isr );
SysSetInterrupt(nHDLCB_INT, HDLCB_isr );
// Step 5. Enable HDLC interrupt
Enable_Int(nHDLCA_INT);
Enable_Int(nHDLCB_INT);
}
/*
* Function : HdlcPortInit
* Description : HDLC Port initialize
*/
int HdlcPortInit(HDLC_Device_Entry *Device)
{
U32 TxInterruptEnableFlag ;
U32 RxInterruptEnableFlag ;
U32 channel ;
channel = Device->HDLC_Port ;
// Step 1. Reset HDLC Controller and HDLC DMA
HCON0(channel) = TxRS | RxRS | DTxRS | DRxRS ;
// Step 2. Set Station address
// This register only used when enable RxASEN. Now, we didn't use
HSADR(channel) = Device->HDLC_Station_Addr ;
// Step 3. Set Baud Rate Generater constant value
HBRGTC(channel)= fMCLK/(2*Device->HDLC_Baud)-1;
// Step 4. Set Preamble value for NRZ code
HPRMB(channel) = HDLC_PREAMBLE ;
// Step 5. Set HDLC Control Register 1
HCON1(channel) = gHCon1 | \
Device->HDLC_Data_format |\
Device->HDLC_Tx_Output_Clk |\
Device->HDLC_Tx_Clk |\
Device->HDLC_Rx_Clk ;
// Step 6. Set HDLC Control Register 0
// Baud-rate Generator Enable, DPLL Enable, Tx/Rx Enable
HCON0(channel) = gHCon0 | \
Device->HDLC_Tx_Clk_Pos | \
Device->HDLC_Rx_Clk_Pos ;
// Step 7. Tx, and Rx Buffer descriptor initialize
TxBDInitialize(channel) ;
RxBDInitialize(channel) ;
// Step 8. Enable HDLC Transmit controller
HDLC_Tx_Enable(channel);
// Step 9. Setup HDLC and HDMA for receive operation
HDLC_Rx_init(channel) ;
// Step 10. Set HDLC Interrupt enable register
if ( Device->HDLC_Tx_Mode == MODE_DMA )
TxInterruptEnableFlag = DTxIE | TxUIE | DTxABIE | DTxSTOPIE ;
else
TxInterruptEnableFlag = TxUIE ;
if ( Device->HDLC_Rx_Mode == MODE_DMA )
RxInterruptEnableFlag = DRxIE | RxABIE | RxFERRIE | RxOVIE | \
DRxSTOPIE | DRxABIE ;
else
RxInterruptEnableFlag = RxABIE | RxFERRIE | RxOVIE | RxFAIE | RxFVIE ;
gHintEn |= TxInterruptEnableFlag | RxInterruptEnableFlag ;
HINTEN(channel) = gHintEn ;
// Step 11. Clear HDLC Status
HSTAT(channel) |= HSTAT(channel) ;
return 1 ;
}
/*
* Function : void TxBDInitialize(U32 channel) ;
* Description : Initialize Tx buffer descriptor area-buffers.
*/
void TxBDInitialize(U32 channel)
{
sBufferDescriptor *pBufferDescriptor;
sBufferDescriptor *pStartBufferDescriptor;
sBufferDescriptor *pLastBufferDescriptor = NULL;
U32 BufferDataAddr;
U32 i;
// Get Buffer descriptor's base address.
// +0x4000000 is for setting this area to non-cacheable area.
gCTxBDPtr[channel] = (U32)TxBDABase[channel] + NonCache ;
pCTxBDPtr[channel] = (U32)TxBDABase[channel] + NonCache ;
// Get Transmit buffer base address.
HDMATXMA(channel) = BufferDataAddr = (U32)TxBABase[channel] + NonCache ;
// Generate linked list.
pBufferDescriptor = (sBufferDescriptor *) gCTxBDPtr[channel];
pStartBufferDescriptor = pBufferDescriptor;
for(i=0; i < MaxTxBufferDescriptor; i++) {
if(pLastBufferDescriptor == NULL)
pLastBufferDescriptor = pBufferDescriptor;
else pLastBufferDescriptor->NextBufferDescriptor = (U32)pBufferDescriptor;
pBufferDescriptor->BufferDataPtr =
(U32)(BufferDataAddr & BOwnership_CPU);
pBufferDescriptor->StatusField = (U32)0x0;
pBufferDescriptor->LengthField = (U32)0x0;
pBufferDescriptor->NextBufferDescriptor = NULL;
pLastBufferDescriptor = pBufferDescriptor;
pBufferDescriptor++;
BufferDataAddr += sizeof(sHDLCFrame);
} // end for loop
// Make Buffer descriptor to ring buffer type.
pBufferDescriptor--;
pBufferDescriptor->NextBufferDescriptor = (U32)pStartBufferDescriptor;
}
/*
* Function : void RxBDInitialize(U32 channel) ;
* Description : Initialize Rx buffer descriptor area-buffers.
*/
void RxBDInitialize(U32 channel)
{
sBufferDescriptor *pBufferDescriptor;
sBufferDescriptor *pStartBufferDescriptor;
sBufferDescriptor *pLastBufferDescriptor = NULL;
U32 BufferDataAddr;
U32 i;
// Get Buffer descriptor's base address.
// +0x4000000 is for setting this area to non-cacheable area.
gCRxBDPtr[channel] = (U32)RxBDABase[channel] + NonCache ;
pCRxBDPtr[channel] = (U32)RxBDABase[channel] + NonCache ;
// Get Transmit buffer base address.
HDMARXMA(channel) = BufferDataAddr = (U32)RxBABase[channel] + NonCache ;
// Generate linked list.
pBufferDescriptor = (sBufferDescriptor *) gCRxBDPtr[channel];
pStartBufferDescriptor = pBufferDescriptor;
for(i=0; i < MaxRxBufferDescriptor; i++) {
if(pLastBufferDescriptor == NULL)
pLastBufferDescriptor = pBufferDescriptor;
else pLastBufferDescriptor->NextBufferDescriptor = (U32)pBufferDescriptor;
pBufferDescriptor->BufferDataPtr =
(U32)(BufferDataAddr | BOwnership_DMA | NonCache );
pBufferDescriptor->StatusField = (U32)0x0;
pBufferDescriptor->LengthField = (U32)0x0;
pBufferDescriptor->NextBufferDescriptor = NULL;
pLastBufferDescriptor = pBufferDescriptor;
pBufferDescriptor++;
BufferDataAddr += sizeof(sHDLCFrame);
} // end for loop
// Make Buffer descriptor to ring buffer type.
pBufferDescriptor--;
pBufferDescriptor->NextBufferDescriptor = (U32)pStartBufferDescriptor;
}
/*
* Function : HDMA_Tx_init
* Description : HDMA Tx DMA initialize
*/
void HDMA_Tx_init(U32 channel, U32 TxDB, int Size)
{
// Initialize HDLC transmit DMA for transmit operation
HDMATXMA(channel) = TxDB ;
HDMATXCNT(channel) = Size ;
}
/*
* Function : HDLC_Rx_init
* Description : HDLC Rx initialize
* return 1 : HDLC receive initialize ok
* return 0 : HDLC receive initialize fail
*/
int HDLC_Rx_init(U32 channel)
{
sBufferDescriptor *CRxBDPtr ;
HDLC_Device_Entry *Dev ;
U32 DataBuffer;
// Step 1. Get HDLC device entry pointer
Dev = (HDLC_Device_Entry *)&HDLC_Dev[channel] ;
// Step 2. Get receive buffer pointer from global variable
CRxBDPtr = (sBufferDescriptor *)gCRxBDPtr[channel] ;
DataBuffer = (U32)CRxBDPtr->BufferDataPtr ;
// Step 3. Check Rx DMA ownership
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -