?? hdlc100init.c
字號:
/****************************************************************/
/* */
/* MODULE: BDTest/hdlc100init.c */
/* DATE: 98/12/01 */
/* PURPOSE: hdlc(high level data link control) header */
/* */
/*--------------------------------------------------------------*/
/* Copyright (C) 1998 Samsung Electronics. */
/* */
/****************************************************************/
#include "snds.h"
#include "hdlc100.h"
#include "sysconf.h"
#include "uart.h"
#include "pollio.h"
#include "timer.h"
#include "isr.h"
#include "dma.h"
#include "memory.h"
#include "kslib.h"
/*
* Function : HdlcInitialize
* Description : This function initiailze the HDLC Block
*/
void HdlcInitialize (void)
{
U8 channel;
U32 UserArea;
for(channel=HDLCA;channel<=HDLCB;channel++)
{
//Reset All HDLC block
HdlcReset(channel) ;
// Internal Register Setting for Tx/Rx operation
HMODE(channel) = gMode ;
#if MODE == DMA
HCON(channel) = gControl ;
HINTEN(channel) = gHIntENA ;
#else
HCONA = Tx1WD|Rx1WD|TxFlag|TxDTR | BRGEN ;
HINTENA = TxFCIE|TxFAIE|TxUIE|RxFAIE|RxFVIE| \
RxABTIE|RxCRCEIE|RxNOIE|RxOVIE ;
#endif
HBRGTC(channel) = GetBaudRate(10000000) ;
AddressSet(channel) ;
#if MODE == DMA
MaxFrameLengthSet(channel,MaxFrameLength);
HRBSR(channel) = RxBufLength ;
// Initialize Buffer Descriptor
TxBD_init(channel,NORMAL,NORMAL) ;
RxBD_init(channel) ;
TxDataWrite(channel,CPU) ;
// Ready to receive Data
HDMARxEN(channel) ;
#endif
HDLCRxEN(channel) ;
}
// Interrupt Vector Setup
SysSetInterrupt(nHDLCTxA_INT, HDLCTxA_isr );
SysSetInterrupt(nHDLCRxA_INT, HDLCRxA_isr );
SysSetInterrupt(nHDLCTxB_INT, HDLCTxB_isr );
SysSetInterrupt(nHDLCRxB_INT, HDLCRxB_isr );
Enable_Int(nHDLCTxA_INT);
Enable_Int(nHDLCRxA_INT);
Enable_Int(nHDLCTxB_INT);
Enable_Int(nHDLCRxB_INT);
Enable_Int(nGLOBAL_INT);
// Initialize Global Variables
gCPUmode = gHdlcRxDone = 0 ;
for(channel=HDLCA;channel<=HDLCB;channel++)
{
gFrameCount[channel]= 0 ;
//initialize User Area
UserArea = (U32) RxUserArea[channel] | NonCache ;
gUserArea[channel] = (U32 *)UserArea ;
}
ClrErrReport() ;
}
/*
* Tx Buffer Descriptor generation &
*/
void TxBD_init(U8 channel,int mode, int arg)
{
sBufferDescriptor *psTxBD ;
sBufferDescriptor *psStartBD ;
sBufferDescriptor *psPrevBD ;
U32 TxBDataStartAddr ;
U32 TxBufLength ;
U32 i ;
U32 MisAlignBytes ;
U32 NullPoint ;
// Mode Set
if(mode == BUFFERLEN) TxBufLength = arg ;
else if(mode == NULLLIST) NullPoint = arg ;
gCTxBDStart[channel] = (U32)sTxBDStart[channel] | NonCache ;
HDMATXPTR(channel) = gCTxBDStart[channel] ;
psTxBD = (sBufferDescriptor *)gCTxBDStart[channel] ;
psStartBD = psTxBD ;
psTxBD->PrevBD = (sBufferDescriptor *)NULL ;
TxBDataStartAddr = (U32)TxBBaseAddr ;
TxBDataStartAddr |= NonCache ;
for(i=1; i<=MaxTxBDCount; i++){
if(mode!=1) TxBufLength = 0x120; //PatternGen(i) & 0x7ff; //debug
if(TxBufLength<6) TxBufLength = 6 ;
MisAlignBytes = (WORD-TxBufLength%WORD)%WORD ;
psTxBD->BufferDataPtr = (U32)TxBDataStartAddr & BOwnerShip_CPU;
psTxBD->Reserved = 0x0;
psTxBD->StatusLength = TxBufLength ;
//Next Buffer Descriptor Allocation
if(psTxBD->PrevBD != (sBufferDescriptor *) NULL){
if(mode==2 && i==NullPoint) {
psPrevBD->NextBD = 0x0 ;
break;
}
else psPrevBD->NextBD = psTxBD ;
}
psPrevBD = psTxBD ; // = psTxBD++
psTxBD++ ;
if(i!=MaxTxBDCount) psTxBD->PrevBD = psPrevBD ;
TxBDataStartAddr += TxBufLength + MisAlignBytes ;
}
psTxBD-- ;
//Assign last buffer descriptor
psTxBD->NextBD = psStartBD ;
//Assign first buffer descriptor
psStartBD->PrevBD = psTxBD ;
}
void TxBufferInitialize(U8 channel)
{
sBufferDescriptor *psTxBD ;
U32 *BufPtr ;
U32 *pBDPtr ;
U32 j, LOOP, TxLength, MisAlignBytes;
U32 u32TxBD ;
// check last flag bit of current Buffer Descriptor
while(1)
{
u32TxBD = (!channel) ? HDMATXPTRA : HDMATXPTRB ;
psTxBD = (sBufferDescriptor *) u32TxBD ;
pBDPtr = (U32 *)&psTxBD->Reserved ;
if(*pBDPtr & LastBF) {
pBDPtr = (U32 *)&psTxBD->BufferDataPtr ;
while (*pBDPtr & BOwnerShip_DMA) ;
break;
}
}
// Write Frame Start Address & change Owner for DMA
BufPtr = (U32 *) ( (U32) TxBBaseAddr + NonCache ) ;
pBDPtr = (U32 *)gCTxBDStart[channel] ;
psTxBD = (sBufferDescriptor *) pBDPtr ;
*pBDPtr |= BOwnerShip_DMA ;
TxLength = (U32)psTxBD->StatusLength & 0xFFFFFF ;
MisAlignBytes = TxLength & 0x3 ;
*BufPtr++ = 0xaaaaaaaa ;
LOOP = (TxLength<4) ? 0 : TxLength/4-1 ;
for(j=0; j<LOOP; j++) *BufPtr++ = j ;
switch(MisAlignBytes) {
case 1 : *BufPtr++ =
(TxLength<<8) & 0xffffff00 | 0x000000cc ; break;
case 2 : *BufPtr++ =
(TxLength<<16) & 0xffff0000 | 0x0000cccc ; break;
case 3 : *BufPtr++ =
(TxLength<<24) & 0xff000000 | 0x00cccccc ; break;
default : break;
}
}
void TxDataWrite(U8 channel,int Owner)
{
sBufferDescriptor *psTxBD ;
U32 *BufPtr ;
U32 *pBDPtr ;
U32 i, j, LOOP, TxLength, MisAlignBytes;
BufPtr = (U32 *) ( (U32) TxBBaseAddr | NonCache ) ;
psTxBD = sTxBDStart[channel] ;
psTxBD = (sBufferDescriptor *) ( (U32) psTxBD | NonCache ) ;
for(i=0; i<MaxTxBDCount; i++){
pBDPtr = (U32 *)&psTxBD->BufferDataPtr ;
if(Owner==DMA) *pBDPtr |= BOwnerShip_DMA ;
psTxBD->Reserved = LastBF;
TxLength = (U32)psTxBD->StatusLength & 0xFFFFFF ;
MisAlignBytes = (WORD-TxLength%WORD)%WORD ;
*BufPtr++ = 0xaaaaaaaa ;
LOOP = (TxLength<4) ? 0 : TxLength/4-1 ;
for(j=0; j<LOOP; j++) *BufPtr++ = 0xffffff00|(j+i) ;
switch(MisAlignBytes) {
case 1 : *BufPtr++ =
(TxLength<<8) & 0xffffff00 | 0x000000cc ; break;
case 2 : *BufPtr++ =
(TxLength<<16) & 0xffff0000 | 0x0000cccc ; break;
case 3 : *BufPtr++ =
(TxLength<<24) & 0xff000000 | 0x00cccccc ; break;
default : break;
}
psTxBD = psTxBD->NextBD ;
}
}
void RxBD_init(U8 channel)
{
sBufferDescriptor *psRxBD ;
sBufferDescriptor *psPrevBD, *psStartBD ;
U32 RxBDataStartAddr ;
U32 i ;
//RxBBaseAddrA = (U32 *)0x200000 ;
gCRxBDStart[channel] = (U32)sRxBDStart[channel] | NonCache ;
HDMARXPTR(channel) = gCRxBDStart[channel] ;
psRxBD = (sBufferDescriptor *)gCRxBDStart[channel] ;
psStartBD = psRxBD ;
psRxBD->PrevBD = (sBufferDescriptor *)NULL ;
RxBDataStartAddr = (U32)RxBBaseAddr[channel] | NonCache ;
for(i=1; i<=MaxRxBDCount; i++){
psRxBD->BufferDataPtr =(U32)RxBDataStartAddr | BOwnerShip_DMA;
psRxBD->Reserved = 0x0 ;
psRxBD->StatusLength = 0x0 ;
//Next Buffer Descriptor Allocation
if(psRxBD->PrevBD != (sBufferDescriptor *) NULL)
psPrevBD->NextBD = psRxBD ;
psPrevBD = psRxBD ; // = psRxBD++
psRxBD++ ;
if(i!=MaxRxBDCount) psRxBD->PrevBD = psPrevBD ;
RxBDataStartAddr += RxBufLength ;
}
//
psRxBD-- ;
//Assign last buffer descriptor
psPrevBD->NextBD = psStartBD ;
//Assign first buffer descriptor
psStartBD->PrevBD = psRxBD ;
}
void HDLCTxA_isr(void)
{
U32 i , j ;
U32 IntHDLCStatus ;
U32 CheckStatus, TxFail ;
U32 PacketSize;
IntHDLCStatus = HSTATA ;
//HSTATA = IntHDLCStatus ;
Clear_PendingBit(nHDLCTxA_INT) ;
TxFail = 0 ;
#if MODE == DMA
if(IntHDLCStatus & DTxFD)
{
gHTxStatus[HDLCA].DMATxFD++ ;
HSTATA = IntHDLCStatus & DTxFD ;
}
CheckStatus = TxSCTS|TxU|DTxABT|DTxNL|DTxNO ;
if(IntHDLCStatus & CheckStatus){
if(IntHDLCStatus & (DTxNO|DTxABT|DTxNL)){
if(IntHDLCStatus & DTxABT){
gHTxStatus[HDLCA].DMATxABT++ ;
HSTATA = IntHDLCStatus & DTxABT ;
}
if(IntHDLCStatus & DTxNO){
gHTxStatus[HDLCA].DMATxNO++ ;
HSTATA = IntHDLCStatus & DTxNO ;
}
if(IntHDLCStatus & DTxNL){
gHTxStatus[HDLCA].DMATxNL++ ;
HSTATA = IntHDLCStatus & DTxNL ;
put_byte('N') ;
}
//TxFail = 1 ;
}
}
if(!CheckTxStatus(HDLCA)|TxFail)
Print("\r HDLCA Tx Fail for Null List") ;
#else
if(IntHDLCStatus & TxFA){
for(i=0; i<gMaxPacketCnt; i++){
PacketSize = PatternGen(i)&0xFFFF;
if(PacketSize < 2) PacketSize = 2 ;
HTXFIFOCA = 0xFFFF0000 | (i+1) ;
for(j=0; j<PacketSize; j++){
if(j==(PacketSize-1)){
HTXFIFOTA = 0xEEEE0000|PacketSize ;
} else HTXFIFOCA = PatternGen(j) | i ;
}
if(i==(gMaxPacketCnt-1))
HINTENA &= ~ TxFAIE ;
}
}
if(IntHDLCStatus & TxFC){
gHTxStatus[HDLCA].TxFrameComp++ ;
}
if(IntHDLCStatus & TxU){
gHTxStatus[HDLCA].TxUnderrun++ ;
}
#endif
}
void HDLCTxB_isr(void)
{
U32 i , j ;
U32 IntHDLCStatus ;
U32 CheckStatus, TxFail ;
U32 PacketSize;
IntHDLCStatus = HSTATB ;
//HSTATB = IntHDLCStatus ;
Clear_PendingBit(nHDLCTxB_INT) ;
TxFail = 0 ;
#if MODE == DMA
if(IntHDLCStatus & DTxFD)
{
gHTxStatus[HDLCB].DMATxFD++ ;
HSTATB = IntHDLCStatus & DTxFD ;
}
CheckStatus = TxSCTS|TxU|DTxABT|DTxNL|DTxNO ;
if(IntHDLCStatus & CheckStatus){
if(IntHDLCStatus & (DTxNO|DTxABT|DTxNL)){
if(IntHDLCStatus & DTxABT){
gHTxStatus[HDLCB].DMATxABT++ ;
HSTATB = IntHDLCStatus & DTxABT ;
}
if(IntHDLCStatus & DTxNO){
gHTxStatus[HDLCB].DMATxNO++ ;
HSTATB = IntHDLCStatus & DTxNO ;
}
if(IntHDLCStatus & DTxNL){
gHTxStatus[HDLCB].DMATxNL++ ;
HSTATB = IntHDLCStatus & DTxNL ;
}
//TxFail = 1 ;
}
}
if(!CheckTxStatus(HDLCB)|TxFail) Print("\r HDLCB Tx Fail") ;
#else
if(IntHDLCStatus & TxFA){
for(i=0; i<gMaxPacketCnt; i++){
PacketSize = PatternGen(i)&0xFFFF;
if(PacketSize < 2) PacketSize = 2 ;
HTXFIFOCB = 0xFFFF0000 | (i+1) ;
for(j=0; j<PacketSize; j++){
if(j==(PacketSize-1)){
HTXFIFOTB = 0xEEEE0000|PacketSize ;
} else HTXFIFOCB = PatternGen(j) | i ;
}
if(i==(gMaxPacketCnt-1))
HINTENB &= ~ TxFAIE ;
}
}
if(IntHDLCStatus & TxFC){
gHTxStatus[HDLCB].TxFrameComp++ ;
}
if(IntHDLCStatus & TxU){
gHTxStatus[HDLCB].TxUnderrun++ ;
}
#endif
}
void HDLCRxA_isr(void)
{
U32 IntHDLCStatus, pRxBDPtr ;
U32 RxFail ;
//U32 CheckStatus,
U32 RemainByte ;
IntHDLCStatus = HSTATA ;
Clear_PendingBit(nHDLCRxA_INT) ;
RxFail = 0 ;
#if MODE == DMA
if(IntHDLCStatus & DRxFD){
gHRxStatus[HDLCA].DMARxFD++ ;
HSTATA = IntHDLCStatus & DRxFD ;
if(IntHDLCStatus & RxFV){
gHRxStatus[HDLCA].RxFValid++ ;
HSTATA = IntHDLCStatus & DRxFD ;
}
if(IntHDLCStatus & RxCRCE) {
gHRxStatus[HDLCA].RxCRCErr++ ;
HSTATA = IntHDLCStatus & DRxFD ;
}
pRxBDPtr = HDMARXPTRA ;
gFrameCount[HDLCA]++;
if(!gMultiTransfer) {
if (!CheckRxStatusHDLC(HDLCA, pRxBDPtr)) RxFail = 1;
}
}
if(IntHDLCStatus & (RxMOV|DRxNL|DRxNO)){//DMARxEN is cleared.
if(IntHDLCStatus & RxMOV) {
gHRxStatus[HDLCA].DMARxMOV++ ;
HSTATA = IntHDLCStatus & RxMOV ;
RxFail = 1;
put_byte('M') ;
}
if(IntHDLCStatus & DRxNL) {
gHRxStatus[HDLCA].DMARxNL++ ;
HSTATA = IntHDLCStatus & DRxNL ;
RxFail = 1;
put_byte('N') ;
}
if(IntHDLCStatus & DRxNO) {
gHRxStatus[HDLCA].DMARxNO++ ;
HSTATA = IntHDLCStatus & RxNO ;
RxFail = 1;
put_byte('O') ;
}
//HDMARxEN(HDLCA) ;
//HDMARXPTRA = gCRxBDStartA ;
}
if(IntHDLCStatus & RxOV) put_byte('.') ;
// 99.1.3 such
if (RxFail) Print("\r HDLCA Rx Fail") ;
#else
if(IntHDLCStatus & (RxFA|RxFV))
{
if(IntHDLCStatus & RxFA)
*gUserArea[HDLCA]++ = HRXFIFOA ;
if(IntHDLCStatus & RxFV)
{ //put_byte('r') ;
gHdlcRxDone = 1 ;
gHRxStatus[HDLCA].RxFValid++ ;
RemainByte = IntHDLCStatus & 0xf;
if(RemainByte == RxRB1)
*gUserArea[HDLCA]++ = HRXFIFOA & 0xFF000000 ;
if(RemainByte == RxRB2)
*gUserArea[HDLCA]++ = HRXFIFOA & 0xFFFF0000 ;
if(RemainByte == RxRB3)
*gUserArea[HDLCA]++ = HRXFIFOA & 0xFFFFFF00 ;
if(RemainByte == RxRB4)
*gUserArea[HDLCA]++ = HRXFIFOA & 0xFFFFFFFF ;
if(!CheckRxCPU()) {
RxFail = 1 ;
gRxFail = 1 ;
}
PrintMemTestStatus(RemainByte%4) ;
}
if(IntHDLCStatus & RxCRCE) {
gHRxStatus[HDLCA].RxCRCErr++ ;
*gUserArea[HDLCA]++ = 0x0000ffff & HRXFIFOA ;
RxFail = 1 ;
}
if(IntHDLCStatus & RxOV) {
gHRxStatus[HDLCA].RxOverrun++ ;
put_byte('O') ;
RxFail = 1 ;
}
if (RxFail) Print("\r HDLCA Rx Fail") ;
}
#endif
}
void HDLCRxB_isr(void)
{
U32 IntHDLCStatus, pRxBDPtr ;
U32 RxFail ;
//U32 CheckStatus,
U32 RemainByte ;
IntHDLCStatus = HSTATB ;
//HSTATB = IntHDLCStatus ;
Clear_PendingBit(nHDLCRxB_INT) ;
RxFail = 0 ;
#if MODE == DMA
if(IntHDLCStatus & DRxFD){
gHRxStatus[HDLCB].DMARxFD++ ;
HSTATB = IntHDLCStatus & DRxFD ;
}
pRxBDPtr = HDMARXPTRB ;
gFrameCount[HDLCB]++;
if(!gMultiTransfer) {
if (!CheckRxStatusHDLC(HDLCB, pRxBDPtr)) RxFail = 1;
}
//while(!(get_byte()=='q'))
// MemoryDump() ;
//gHdlcRxDone = 1;
//99.1.3 such
if(IntHDLCStatus & (RxMOV|DRxNL|DRxNO)){//DMARxEN is cleared.
if(IntHDLCStatus & RxMOV) {
gHRxStatus[HDLCB].DMARxMOV++ ;
HSTATB = IntHDLCStatus & RxMOV ;
RxFail = 1;
}
if(IntHDLCStatus & DRxNL) {
gHRxStatus[HDLCB].DMARxNL++ ;
HSTATB = IntHDLCStatus & DRxNL ;
RxFail = 1;
}
if(IntHDLCStatus & DRxNO) {
gHRxStatus[HDLCB].DMARxNO++ ;
HSTATB = IntHDLCStatus & RxNO ;
RxFail = 1;
}
HDMARxEN(HDLCB) ;//cjw. need to check, this line can be
//operated in CheckRxStatus()
HDMARXPTRB = gCRxBDStart[HDLCB] ;
}
// 99.1.3 such
if (RxFail) Print("\r HDLCB Rx Fail") ;
#else
if(IntHDLCStatus & (RxFA|RxFV))
{
if(IntHDLCStatus & RxFA)
*gUserArea[HDLCB]++ = HRXFIFOB ;
if(IntHDLCStatus & RxFV)
{
gHdlcRxDone = 2 ;
gHRxStatus[HDLCB].RxFValid++ ;
RemainByte = IntHDLCStatus & 0xf;
if(RemainByte == RxRB1)
*gUserArea[HDLCB]++ = HRXFIFOB & 0xFF000000 ;
if(RemainByte == RxRB2)
*gUserArea[HDLCB]++ = HRXFIFOB & 0xFFFF0000 ;
if(RemainByte == RxRB3)
*gUserArea[HDLCB]++ = HRXFIFOB & 0xFFFFFF00 ;
if(RemainByte == RxRB4)
*gUserArea[HDLCB]++ = HRXFIFOB & 0xFFFFFFFF ;
if(!CheckRxCPU()) {
RxFail = 1 ;
gRxFail = 1 ;
}
PrintMemTestStatus(RemainByte%4) ;
}
//if(IntHDLCStatus & RxFA)
//*gUserAreaB++ = HRXFIFOB ;
if(IntHDLCStatus & RxCRCE) {
gHRxStatus[HDLCB].RxCRCErr++ ;
*gUserArea[HDLCB]++ = 0x0000ffff & HRXFIFOB ;
RxFail = 1 ;
}
if(IntHDLCStatus & RxOV) {
gHRxStatus[HDLCB].RxOverrun++ ;
put_byte('O') ;
RxFail = 1 ;
}
if (RxFail) Print("\r HDLCB Rx Fail") ;
}
#endif
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -