/********************************************************************* DLC1.C Data Link Control Route 56 Developer's Toolkit 1995 (C) Copyright Sealevel Systems, Inc., 1995 ********************************************************************** History: 07-19-95 JGY Original module 12-08-95 JGY Updated buffer routines *********************************************************************/ #include #include #include #include #include #include #include #include #include /******************************************************************* Systems Resources *******************************************************************/ #define PORT 0x300 #define IRQ 11 #define MAX_BUFFERS (MEM_PAGE_LAST) #define TX_ARRAY_OFFSET 0x200 #define RX_ARRAY_OFFSET 0x400 #define BUFFER_LENGTH 0x2000 /******************************************************************* Z16C32 IUSC Init Values *******************************************************************/ WORD InitValues[]={ BCR |writeW, BRQ_Signal_TotemPole | BusWidth_16BitBus | IRQ_Signal_OpenDrain | ShiftedAddr_ShiftRightMode, /* bus configuration */ PCR |writeW|checkW, Port7_PinCtrl_Output1 | /* RTS off */ Port6_PinCtrl_Output1 | /* DTR off */ Port5_PinCtrl_Output0 | /* Enable TxC driver to modem */ Port3_PinCtrl_Output1 | /* balanced TxD,TxC drive (RS-449, V.35, X.21) */ Port2_PinCtrl_Output1 | /* balanced RTS,DTR drive (RS-449, X.21) */ Port1_PinCtrl_Output0 | /* Drive P1 low, not used */ Port0_PinCtrl_CTR0_Clock, /* P0 is on board OSC input */ /* block serial data out for internal loopback */ IOCR|writeW|checkW, TxC_PinControl_TxClkOutput | TxD_PinControl_TxDataOutput, /* use P0 clock not CTR0 */ CCSR|writeW|checkL, RCC_FIFO_Clear_Reset | PORT0_1BypassCTR_Yes, CMCR|writeW|checkW, BRG0_ClkSource_CTR0_Output | TxClkSource_BRG0_Output| RxClkSource_RxC_Pin, TC0R|writeW|checkW, 10, /* 16/(10+1)=1.4545... Mbps was */ HCR |writeW|checkW, BRG0_Enable_Yes, /* enable BRG0 */ CCR |writeW|checkW, TxCtrlBlockXfer_2WordCtrlBlock | RxStatBlockXfer_2WordStatBlock, CMR |writeW|checkW, TxMode_HDLC | /* Rx HDLC operation */ TxUnderCondHDLC_ExtendedAbort| RxMode_HDLC, /* Rx HDLC operation */ RICR|checkH, 0, /* Make sure Rx FIFO is empty */ /*unlatch all status flags*/ RCSR|writeW, RxCommand_SelectIntLevel | 0x1FF, RICR|writeW|checkW, 31* 0x100 | StatusOn_Words, RCSR|writeH, RxCommand_SelectReqLevel, RICR|writeH|checkH, 11* 0x100, /* RxDMA 12 bytes in FIFO */ RCSR|writeH, RxCommand_SelectFilLevel, RICR|checkH, 0, /* check fill level 0 */ RCLR|writeW|checkW, (WORD)-1, TICR|checkH, 32* 0x100, /* check Tx FIFO empty */ TCSR|writeW, TxCommand_SelectIntLevel | 0xFF, TICR|writeW|checkW, 31* 0x100, TCSR|writeH, TxCommand_SelectReqLevel, TICR|writeH|checkH, 11* 0x100, /* TxDMA 12 bytes in FIFO */ TCSR|writeH, TxCommand_SelectFilLevel, TICR|checkH, 32* 0x100, /* check TX emptiness level */ DCCR|writeW, IP_Command_ResetIP_IUS | 0x3F, /* clear all serial IP & IUS */ DCR |writeW|checkW, BinaryValueOrder_Z80_Intel | ChannelPriority_Rx, RDMR|writeW|checkW, RxChannelMode_LinkedList| RxDMAAdvStatHdl_Yes| RxTermEnable_Yes | RxDMAWriteBack0_Yes, TDMR|writeW|checkW, TxChannelMode_LinkedList| TxDMAAdvStatHdl_Yes | TxDMAWriteBack0_Yes, CCAR|writeW, ChannelCommand_SelctD7_0_1st | ModeControl_NormalOp, CCAR|checkH, ModeControl_NormalOp, /* check CCAR readback */ TMR |writeW|checkW, TxCRC_Polynomial_CRC_CCITT| TxCRC_PresetVal_Ones| TxCRC_Enable_Yes| TxCRC_On_EOF_EOM_Yes| TxEnable_Enable, RMR |writeW|checkW, RxCRC_Polynomial_CRC_CCITT| RxCRC_PresetVal_Ones| RxCRC_Enable_Yes| RxAbortHandling_Yes | RxEnable_Enable, (WORD)-1}; /* end of table*/ /*******************************************************************/ #define LOOP_COUNT 45 /*Test string length for Tx*/ BYTE txbuff[]="The Quick Brown Fox Jumped Over The Lazy Dog.\0"; WORD ERROR_PARITY = 0, ERROR_OVERRUN = 0, ERROR_CRC = 0; WORD FRAME_COUNT_TX = 0, FRAME_COUNT_RX = 0; WORD INT_COUNT_TOTAL = 0, INT_COUNT_SERIAL_MISC = 0, INT_COUNT_SERIAL_IO = 0; WORD INT_COUNT_SERIAL_TX_DATA = 0, INT_COUNT_SERIAL_TX_STATUS = 0; WORD INT_COUNT_SERIAL_RX_DATA = 0, INT_COUNT_SERIAL_RX_STATUS = 0; WORD INT_COUNT_NULL = 0, INT_COUNT_DMA_TX = 0, INT_COUNT_DMA_RX = 0; WORD STATUS_RESTART_TX = 0; STATUS_RESTART_RX = 0; VOID INTERRUPT FAR IUSC_isr(VOID); static VOID IUSC_Serial_Misc_Int (VOID); static VOID IUSC_Serial_IO_Pin_Int (VOID); static VOID IUSC_Serial_Tx_Data_Int (VOID); static VOID IUSC_Serial_Tx_Status_Int (VOID); static VOID IUSC_Serial_Rx_Data_Int (VOID); static VOID IUSC_Serial_Rx_Status_Int (VOID); static VOID IUSC_NULL_Int (VOID); static VOID IUSC_DMA_Tx_Int (VOID); static VOID IUSC_DMA_Rx_Int (VOID); /******************************************************************* Stuff for IRQ Setup Routines *******************************************************************/ VOID IRQRemove(BYTE ); VOID IRQSetup(BYTE , VOIDINTPROC ); BYTE XT_PIC_MASK; BYTE AT_PIC_MASK; VOIDINTPROC OldIRQVector; /*******************************************************************/ R56_INFO CARD1; /*Card Info Struct*/ R56_INFO * fpCARD1 = &CARD1; /*Card Info Struct Ptr*/ VOID DumpStruct(VOID); VOID printbuf(LPBYTE, WORD); VOID WriteLink(fpR56_INFO, WORD, BYTE); int QueueTxFrame(fpR56_INFO , LPBYTE ,WORD ); int PrintRxFrameInQueue(fpR56_INFO ); /******************************************************************* Main Program Entry Point *******************************************************************/ int main (int argc,char *argv[]) { BYTE c; WORD wTemp; /* Define I/O resources used in this test*/ fpCARD1->wIOAddress = PORT; fpCARD1->IUSCIRQ = IRQ; fpCARD1->InitArray = (LPWORD) &InitValues; fpCARD1->MemoryBase = (CHAR FAR *) 0xd0000000; fpCARD1->IUSCISR = IUSC_isr; fpCARD1->wTotalRxFrames = MAX_BUFFERS; fpCARD1->wTotalTxFrames = MAX_BUFFERS; fpCARD1->wRedTxFrames = 0; fpCARD1->wRedRxFrames = MAX_BUFFERS - 1; fpCARD1->wAppTxFrame = 0; fpCARD1->wAppRxFrame = 0; fpCARD1->wISRTxFrame = 0; fpCARD1->wISRRxFrame = 0; fpCARD1->wTxArrayOffset = 0x200; fpCARD1->wRxArrayOffset = 0x400; fpCARD1->TxLinkList = (fpIUSCLINKLISTDMA)(fpCARD1->MemoryBase + fpCARD1->wTxArrayOffset); fpCARD1->RxLinkList = (fpIUSCLINKLISTDMA)(fpCARD1->MemoryBase + fpCARD1->wRxArrayOffset); printf("\nRoute 56 WAN Adapter Test Program.\n\n"); printf("Type \"T\" to transmit and \"X\" to exit to DOS.\n\n"); /* Verify Presence of the Card*/ if(VerifyR56(fpCARD1)) {printf("Error: Incorrect I/O address or adapter is not responding at %X HEX. \n",fpCARD1->wIOAddress); DisableR56(fpCARD1); return(1); } /* Reset IUSC */ if((0 != LOWORD(ResetIUSC(fpCARD1)))) /* if reset error*/ {printf("Error: Failure Resetting the IUSC.\n\7\7\7"); DisableR56(fpCARD1); return(1); } if(InitIUSC(fpCARD1)) /*Init IUSC */ {printf("Error: Failure initializing the IUSC.\n"); DisableR56(fpCARD1); return(1); } SetR56Interface(fpCARD1, SET_EIA530); /* Set interface to EIA-530*/ SetR56Clock(fpCARD1, SET_TXC_OUTPUT); /* Set Tx Clock as output*/ IUSCout(fpCARD1, CCAR, ModeControl_NormalOp | ChannelCommand_RxTxFIFO_Purge); /*Setup the IRQ and ISR,Save/Replace Interrupt Vector. */ IRQSetup(fpCARD1->IUSCIRQ ,fpCARD1->IUSCISR); IUSCout(fpCARD1,TDIAR, TxEOB_IA_Yes | TxEOA_EOL_IA_Yes); IUSCout(fpCARD1,RDIAR, RxEOB_IA_Yes | RxEOA_EOL_IA_Yes); /*Not needed, no serial Ints at this time */ IUSCout(fpCARD1,ICR, MasterIntEnable_Yes | VectIncludeStat_Yes ); IUSCout(fpCARD1,DICR, DMA_MasterIntEn_Yes | DMA_VectInclStat_Yes | DMA_Rx_IE_Yes | DMA_Tx_IE_Yes ); /* Set internal loop bit*/ // IUSCout(fpCARD1,IOCR,TxC_PinControl_TxClkOutput | TxD_PinControl_Output1); IUSCout(fpCARD1,CCAR, ModeControl_NormalOp ); IUSCout(fpCARD1,DCAR, DMA_ChannelCmd_PauseBoth); WriteLink(fpCARD1, MAX_BUFFERS, 1); IUSCout(fpCARD1,NRARU, 0x000); /* Next Rx Address*/ IUSCout(fpCARD1,NRARL, fpCARD1->wRxArrayOffset); /* Start the receiver */ IUSCout(fpCARD1,DCAR, DMA_ChannelCmd_StartInitChanl | Channel_Rx | MasterBusReqEn_Yes); fpCARD1->bStatus = fpCARD1->bStatus | (BYTE) ST_TX_STOPPED; do { c = 0; if(_bios_keybrd(_KEYBRD_READY)) {c=(unsigned char)_bios_keybrd(_KEYBRD_READ); switch(c) {case 'x': case 'X': c = 'x'; break; case 't': case 'T': /*Fill all Tx frame buffers*/ for(wTemp = 0; wTemp < (MAX_BUFFERS-2); wTemp++) {if(0==QueueTxFrame(fpCARD1,(LPBYTE)&txbuff,LOOP_COUNT)) break; } break; default: break; } /*end switch case*/ } /*end if*/ // if(fpCARD1->wRedTxFrames <= 5) // for(wTemp = 0; wTemp < 5; wTemp++) // {if(0==QueueTxFrame(fpCARD1,(LPBYTE)&txbuff,LOOP_COUNT)) // break; // } for(wTemp = 0; wTemp < 7; wTemp++) PrintRxFrameInQueue(fpCARD1); printf("Tx: %X, Rx: %X ,",fpCARD1->wRedTxFrames,fpCARD1->wRedRxFrames); printf("Tx: %X, Rx: %X ,",fpCARD1->wAppTxFrame,fpCARD1->wAppRxFrame); printf("Tx: %X, Rx: %X \r",fpCARD1->wISRTxFrame,fpCARD1->wISRRxFrame); } while(c != 'x'); /* Stop both DMA channels*/ IUSCout(fpCARD1,DCAR, DMA_ChannelCmd_PauseBoth); /* Purge any Rx Buffers left*/ for(wTemp = 0; wTemp < MAX_BUFFERS ; wTemp++) PrintRxFrameInQueue(fpCARD1); /*reset internal loop bit */ IUSCout(fpCARD1,CCR, 0); IUSCout(fpCARD1,IOCR,TxC_PinControl_TxClkOutput | TxD_PinControl_TxDataOutput); IUSCout(fpCARD1,CCAR, ModeControl_NormalOp ); // DumpStruct(); /* Disable IUSC Interrupts*/ IUSCout(fpCARD1,ICR, MasterIntEnable_No); IUSCout(fpCARD1,DICR, DMA_MasterIntEn_No ); IRQRemove(fpCARD1->IUSCIRQ); /*Restore Interrupt Vector, etc. */ printf("\nTx Frames : %d , Rx Frames : %d \n", FRAME_COUNT_TX, FRAME_COUNT_RX); if(INT_COUNT_TOTAL) printf("Interrupts : %d\n", INT_COUNT_TOTAL); if(INT_COUNT_SERIAL_MISC) printf("Misc Serial Interrupts : %d\n", INT_COUNT_SERIAL_MISC); if(INT_COUNT_SERIAL_IO) printf("I/O Serial Interrupts : %d\n", INT_COUNT_SERIAL_IO); if(INT_COUNT_SERIAL_RX_DATA) printf("Rx Data Interrupts : %d\n", INT_COUNT_SERIAL_RX_DATA); if(INT_COUNT_SERIAL_RX_STATUS) printf("Rx Status Interrupts : %d\n", INT_COUNT_SERIAL_RX_STATUS); if(INT_COUNT_SERIAL_TX_DATA) printf("Tx Data Interrupts : %d\n", INT_COUNT_SERIAL_TX_DATA); if(INT_COUNT_SERIAL_TX_STATUS) printf("Tx Status Interrupts : %d\n", INT_COUNT_SERIAL_TX_STATUS); if(INT_COUNT_NULL) printf("Null Interrupts : %d\n", INT_COUNT_NULL); if(INT_COUNT_DMA_TX) printf("Tx DMA Interrupts : %d\n", INT_COUNT_DMA_TX); if(INT_COUNT_DMA_RX) printf("Rx DMA Interrupts : %d\n", INT_COUNT_DMA_RX); if(STATUS_RESTART_RX) printf("Rx Restarts: %d\n",STATUS_RESTART_RX); if(STATUS_RESTART_TX) printf("Tx Restarts: %d\n",STATUS_RESTART_TX); if(ERROR_PARITY) printf("Parity Error(s): %d\n",ERROR_PARITY); if(ERROR_OVERRUN) printf("Rx Overrun Error(s): %d\n",ERROR_OVERRUN); if(ERROR_CRC) printf("CRC Error(s): %d\n",ERROR_CRC); DisableR56(fpCARD1); return(0); } /******************************************************************* DumpStruct() *******************************************************************/ VOID DumpStruct(VOID) { WORD i; OUT(fpCARD1->wIOAddress, IUSC_DISABLE | MEM_WIN_ON | MEM_PAGE_FIRST); for(i = 0; i < MAX_BUFFERS; i++) printf("%x,",CARD1.RxLinkList[i].wByteCount); printf("\n"); } /******************************************************************* QueueTxFrame This will queue the specified frame in the Tx Frame buffer. *******************************************************************/ int QueueTxFrame(fpR56_INFO fpCard, LPBYTE TxFrame,WORD wLength) { WORD wFramePtr; if(wLength > BUFFER_LENGTH) /* make sure we do not over fill */ wLength = BUFFER_LENGTH; /* the buffer*/ if(fpCard->wRedTxFrames >= (MAX_BUFFERS -1)) return(0); /* Return, No Room in buffer*/ if(fpCard->wAppTxFrame >= MAX_BUFFERS) return(0); /* Return, Invalid buffer ptr*/ wFramePtr = fpCard->wAppTxFrame; OUT(fpCard->wIOAddress, IUSC_DISABLE | MEM_WIN_ON | MEM_PAGE_FIRST); ChangeR56Page(fpCard,(BYTE) ((wFramePtr) + 1)); /*move the frame into our queue*/ _fmemmove(fpCard->MemoryBase, TxFrame, wLength); /*move the frame into our queue*/ ChangeR56Page(fpCard,MEM_PAGE_FIRST); fpCard->TxLinkList[wFramePtr].wCCLength = wLength; /*Max Length*/ fpCard->TxLinkList[wFramePtr].wByteCount = wLength; /* Frame Length*/ fpCard->wRedTxFrames++; if(fpCard->bStatus & ST_TX_STOPPED) // if( fpCard->wAppTxFrame == fpCard->wISRTxFrame) {IUSCout(fpCard,NTARU, 0x000); /* Next Tx Address*/ IUSCout(fpCard,NTARL, fpCard->wTxArrayOffset + (fpCard->wAppTxFrame * sizeof(IUSCLINKLISTDMA))); IUSCout(fpCard,CCAR, ChannelCommand_LoadTxCharCt | ModeControl_NormalOp); STATUS_RESTART_TX++; fpCard->bStatus = fpCard->bStatus & (BYTE) ~ST_TX_STOPPED; IUSCout(fpCard,DCAR, DMA_ChannelCmd_StartInitChanl | Channel_Tx | MasterBusReqEn_Yes); /*Restart the device*/ } if( fpCard->wAppTxFrame == (MAX_BUFFERS - 1)) fpCard->wAppTxFrame = 0; else fpCard->wAppTxFrame++; return(1); } /******************************************************************* PrintRxFrameInQueue This routine will fetch a received frame from the Rx Frame buffer and display the contents on the screen. If no frames are available then a zero is returned. *******************************************************************/ int PrintRxFrameInQueue(fpR56_INFO fpCard) { LPBYTE fpTemp; WORD wFramePtr, wFrameLength; if(fpCard->wRedRxFrames >= MAX_BUFFERS-1) return(0); /* Return, No available buffers*/ if(fpCard->wAppRxFrame >= MAX_BUFFERS) return(0); /* Return, Invalid buffer ptr*/ wFramePtr = fpCard->wAppRxFrame; OUT(fpCard->wIOAddress, IUSC_DISABLE | MEM_WIN_ON | MEM_PAGE_FIRST); ChangeR56Page(fpCard, 0); if(fpCard->RxLinkList[wFramePtr].wCCLength != 0) wFrameLength = 0xffff - (fpCard->RxLinkList[wFramePtr].wCCLength); else wFrameLength = 2; ChangeR56Page(fpCard,(BYTE) ((wFramePtr) + 1)); /*move the frame into our queue*/ fpTemp = (fpCard->MemoryBase + BUFFER_LENGTH); printbuf(fpTemp, wFrameLength - 2); ChangeR56Page(fpCard, 0); fpCard->RxLinkList[wFramePtr].wByteCount = BUFFER_LENGTH; /* Frame Length*/ fpCard->RxLinkList[wFramePtr].wCCLength = BUFFER_LENGTH; fpCard->wRedRxFrames++; if(fpCard->bStatus & ST_RX_STOPPED) {IUSCout(fpCard,NRARU, 0x000); /* Next Rx Address*/ IUSCout(fpCard,NRARL, fpCard->wRxArrayOffset + (fpCard->wAppRxFrame * sizeof(IUSCLINKLISTDMA))); fpCard->bStatus = fpCard->bStatus & (BYTE) ~ST_RX_STOPPED; STATUS_RESTART_RX++; IUSCout(fpCard,DCAR, DMA_ChannelCmd_StartInitChanl | Channel_Rx | MasterBusReqEn_Yes); } if( fpCard->wAppRxFrame == (MAX_BUFFERS - 1)) fpCard->wAppRxFrame = 0; else fpCard->wAppRxFrame++; return(1); } /*******************************************************************/ /* This routine will print the specified buffer */ /* Note that a CR LF is added to the end. */ /*******************************************************************/ VOID printbuf( LPBYTE buf, WORD wLength) { WORD i; if(wLength > BUFFER_LENGTH) wLength = BUFFER_LENGTH; for (i = 0; i < wLength; i++) printf("%c", buf[i]); printf("\n"); // if(wLength != 0) // { printf("\nLen:%X:,",wLength); // DumpStruct(); // } } /******************************************************************* WriteLink : This routine will put a link list array of nNumBuffers on the first (0) page. Each buffer in the link starts on a new page. The starting buffer is specified by bPage. *******************************************************************/ VOID WriteLink(fpR56_INFO fpCard, WORD wNumBuffers, BYTE bPage) { DWORD lTempPage; WORD i; OUT(fpCard->wIOAddress, IUSC_DISABLE | MEM_WIN_ON | MEM_PAGE_FIRST); fpCard->TxLinkList = (fpIUSCLINKLISTDMA)(fpCard->MemoryBase + fpCard->wTxArrayOffset); fpCard->RxLinkList = (fpIUSCLINKLISTDMA)(fpCard->MemoryBase + fpCard->wRxArrayOffset); ChangeR56Page(fpCard, MEM_PAGE_0); /* point to page zero*/ /* Address = (Page*4) << 0x10;*/ /* first do the Tx Link List */ lTempPage = bPage; for( i = 0; i < wNumBuffers; i++) { fpCard->TxLinkList[i].lBufferAddress = ((lTempPage * 4) << 0x0c); lTempPage++; fpCard->TxLinkList[i].wByteCount = 0; /* word Char Count*/ fpCard->TxLinkList[i].wCSB = 0; fpCard->TxLinkList[i].wCCLength = 0; fpCard->TxLinkList[i].wNotUsed = 0xffff; fpCard->TxLinkList[i].lNextAddress = fpCard->wTxArrayOffset + ((i+1) * sizeof(IUSCLINKLISTDMA)); } fpCard->TxLinkList[wNumBuffers - 1].lNextAddress = fpCard->wTxArrayOffset; /* Now do the Rx Link List*/ lTempPage = bPage; for( i = 0; i < wNumBuffers; i++) { fpCard->RxLinkList[i].lBufferAddress = ((lTempPage * 4) << 0x0c) + BUFFER_LENGTH; lTempPage++; fpCard->RxLinkList[i].wByteCount = BUFFER_LENGTH; /* word Char Count*/ fpCard->RxLinkList[i].wCSB = 0; fpCard->RxLinkList[i].wCCLength = BUFFER_LENGTH; fpCard->RxLinkList[i].wNotUsed = 0xffff; fpCard->RxLinkList[i].lNextAddress = fpCard->wRxArrayOffset + ((i+1) * sizeof(IUSCLINKLISTDMA)); } fpCard->RxLinkList[wNumBuffers - 1].lNextAddress = fpCard->wRxArrayOffset; } /******************************************************************* IRQSetup : This routine will replace the specified Interrupt Vector and setup the XT and AT PIC. *******************************************************************/ VOID IRQSetup(BYTE bIRQ, VOIDINTPROC fpISR) { BYTE bNumber; XT_PIC_MASK = (BYTE) IN( 0x21); /*Save the PIC Mask*/ AT_PIC_MASK = (BYTE) IN( 0xA1); if(bIRQ < 8) /* Setup the IRQ Vector*/ bNumber = 0x08 + bIRQ; /* i.e IRQ2 = 0x0a*/ else bNumber = 0x68 + bIRQ; /* i.e IRQ9 = 0x71*/ OldIRQVector = _dos_getvect(bNumber); _dos_setvect(bNumber, (VOIDINTPROC) fpISR); if(bIRQ < 8) {bNumber = 0x01 << bIRQ; OUT(0x21, (~bNumber & IN(0x21))); } else {OUT(0x21,( 0xfb & IN(0x21))); /*mask IRQ2*/ bNumber = 0x01 << (bIRQ - 8); OUT(0xA1, (~bNumber & IN(0xA1))); } } /******************************************************************* IRQRemove : This routine will restore the specified Interrupt Vector and restore the XT and AT PIC. *******************************************************************/ VOID IRQRemove(BYTE bIRQ) { BYTE bNumber; /*Restore the PIC Mask*/ OUT(0x21, XT_PIC_MASK); OUT(0xA1, AT_PIC_MASK); /* Setup the IRQ Vector*/ if(bIRQ < 8) bNumber = 0x08 + bIRQ; /* i.e IRQ2 = 0x0a*/ else bNumber = 0x68 + bIRQ; /* i.e IRQ9 = 0x71*/ _dos_setvect(bNumber, OldIRQVector); return; } /******************************************************************* WARNING : Everything below this point can be called at interrupt time and should have stack checking turned off. *******************************************************************/ #pragma check_stack(off) /******************************************************************* IUSC_isr : FAR : ISR IUSC Interrupt Service Routine Entry Point *******************************************************************/ VOID INTERRUPT FAR IUSC_isr(VOID) { static WORD wISRptr; static VOID (*SerialInt[7])(VOID) = { IUSC_NULL_Int, IUSC_Serial_Misc_Int, /* This is an array of routines */ IUSC_Serial_IO_Pin_Int, /* that are called when an */ IUSC_Serial_Tx_Data_Int, /* interrupt is pending on the */ IUSC_Serial_Tx_Status_Int, /* Serial Section of the Z16C32.*/ IUSC_Serial_Rx_Data_Int, IUSC_Serial_Rx_Status_Int, }; static VOID (*DMAInt[4])(VOID) = { IUSC_NULL_Int, /* This is an array of routines */ IUSC_NULL_Int, /* that are called when an */ IUSC_DMA_Tx_Int, /* interrupt is pending on the */ IUSC_DMA_Rx_Int, /* DMA Section of the Z16C32.*/ }; INT_COUNT_TOTAL++; do{ while ( 0 !=( wISRptr = (IUSCin(fpCARD1, IVR) & 0x0e00))) {wISRptr >>= 9; (*SerialInt[wISRptr])(); } while(IUSCin(fpCARD1,SDIR) & (DMA_RxIP_Yes | DMA_TxIP_Yes)) {wISRptr = IUSCin(fpCARD1, DIVR); wISRptr = wISRptr & 0x0600; wISRptr >>= 9; (*DMAInt[wISRptr])(); } } while( 0 == (IN(fpCARD1->wIOAddress + 3) & IRQ_ACTIVE)); if(fpCARD1->IUSCIRQ > 7) OUT(0xa0 ,0x20); /* AT PIC EOI */ OUT(0x20, 0x20); /* XT PIC EOI */ } /******************************************************************* IUSC_Serial_Misc_Int : NEAR : Called from ISR *******************************************************************/ static VOID IUSC_Serial_Misc_Int (VOID) { INT_COUNT_SERIAL_MISC++; IUSCout(fpCARD1,DCCR, IP_Command_ResetIP | DeviceStatusIP_Yes); } /******************************************************************* IUSC_Serial_IO_Pin_Int : NEAR : Called from ISR *******************************************************************/ static VOID IUSC_Serial_IO_Pin_Int (VOID) { INT_COUNT_SERIAL_MISC++; IUSCout(fpCARD1,DCCR, IP_Command_ResetIP | IO_StatusIP_Yes); } /******************************************************************* IUSC_Serial_Tx_Data_Int : NEAR : Called from ISR *******************************************************************/ static VOID IUSC_Serial_Tx_Data_Int (VOID) { INT_COUNT_SERIAL_TX_DATA++; IUSCout(fpCARD1,DCCR, IP_Command_ResetIP | TxDataIP_Yes); } /******************************************************************* IUSC_Serial_Tx_Status_Int : NEAR : Called from ISR *******************************************************************/ static VOID IUSC_Serial_Tx_Status_Int (VOID) { INT_COUNT_SERIAL_TX_STATUS++; IUSCout(fpCARD1,DCCR, IP_Command_ResetIP | TxStatusIP_Yes); } /******************************************************************* IUSC_Serial_Rx_Data_Int : NEAR : Called from ISR *******************************************************************/ static VOID IUSC_Serial_Rx_Data_Int (VOID) { INT_COUNT_SERIAL_RX_DATA++; IUSCout(fpCARD1,DCCR, IP_Command_ResetIP | RxDataIP_Yes); } /******************************************************************* IUSC_Serial_Rx_Status_Int : NEAR : Called from ISR *******************************************************************/ static VOID IUSC_Serial_Rx_Status_Int (VOID) { INT_COUNT_SERIAL_RX_STATUS++; IUSCout(fpCARD1,DCCR, IP_Command_ResetIP | RxStatusIP_Yes); } /******************************************************************* IUSC_NULL_Int : NEAR : Called from ISR *******************************************************************/ static VOID IUSC_NULL_Int (VOID) { INT_COUNT_NULL++; } /******************************************************************* IUSC_DMA_Tx_Int : NEAR : Called from ISR *******************************************************************/ static VOID IUSC_DMA_Tx_Int (VOID) { static WORD wDMATx; INT_COUNT_DMA_TX++; IUSCout(fpCARD1,CDIR, ResetDMA_TxIP_Reset); wDMATx = IUSCin(fpCARD1, TDMR); if(wDMATx & TxEOB_Yes) {FRAME_COUNT_TX++; fpCARD1->wRedTxFrames--; if( fpCARD1->wISRTxFrame == (MAX_BUFFERS - 1)) fpCARD1->wISRTxFrame = 0; else fpCARD1->wISRTxFrame++; } if(wDMATx & TxEOA_EOL_Yes) /*Is the next link available*/ {if(fpCARD1->wISRTxFrame == fpCARD1->wAppTxFrame) fpCARD1->bStatus = fpCARD1->bStatus | ST_TX_STOPPED; } } /******************************************************************* IUSC_DMA_Rx_Int : NEAR : Called from ISR *******************************************************************/ static VOID IUSC_DMA_Rx_Int (VOID) { static WORD wDMARx; INT_COUNT_DMA_RX++; IUSCout(fpCARD1,CDIR, ResetDMA_RxIP_Reset); wDMARx = IUSCin(fpCARD1, RDMR); if(wDMARx & RxEOB_Yes) {FRAME_COUNT_RX++; fpCARD1->wRedRxFrames--; if( fpCARD1->wISRRxFrame == (MAX_BUFFERS - 1)) fpCARD1->wISRRxFrame = 0; else fpCARD1->wISRRxFrame++; } if(wDMARx & RxEOA_EOL_Yes) /*Is the next link available*/ fpCARD1->bStatus = fpCARD1->bStatus | ST_RX_STOPPED; } #pragma check_stack() /******************************************************************* End of File *******************************************************************/