/*******************************************************************/ /* Advanced Communication Board Developer Toolkit */ /* (c)Copyright 1996, Sealevel Systems Incorporated */ /* */ /* Please read the program abstract for details on this program. */ /* */ /* INT3.C */ /* 08-23-96 vsg updated Rx. sync/hunt operation */ /*******************************************************************/ #include #include #include #include "acb.h" #include "int.h" #define Z85230 #define Z85C30 #include "Z8530.h" #include "ASCII.h" /* or EBCDIC.h for other character codes */ /*******************************************************************/ /* Things to make the program "compiler friendly"! */ /*******************************************************************/ #ifndef _BORLAND #define IN _inp #define OUT _outp #define FAR __far #define INTERRUPT __cdecl __far __interrupt #define KBHIT _kbhit #else #define IN inport #define OUT outport #define FAR far #define INTERRUPT far interrupt #define KBHIT kbhit #endif /*******************************************************************/ #define PORT 0x238 /* Base Address of ACB card */ #define IRQ 0x05 /* interrupt request (IRQ 2-15) */ #define MAX_BUFFER 500 /* Size of Rx Buffer */ #define ECHO 0 /* 1 is echo on */ /*******************************************************************/ /* Z85x30 Init Values */ /*******************************************************************/ #define PRAM_COUNT 54 unsigned char init[PRAM_COUNT]= /*BISYNC initialization */ { WR0,NULL_CODE, /* MODES */ WR4, X1_CLOCK | SYNC_MODE_ENABLE | SYNC_16_BIT, WR1, WAIT_DMA_DISABLE | INT_DISABLE, WR2, 0x00, /* not used in polled mode */ WR3, RX_8_BITS | RX_CRC_ENABLE | SYNC_CHAR_LOAD_INHIBIT , WR5, TX_8_BITS | CRC_16 | TX_CRC_ENABLE, WR6, SYN, /* SYNC Flag Low*/ WR7, SYN, /* SYCN Flag High*/ WR9, MI_DISABLE, WR10, CRC_PRESET_TO_ZERO, WR11, TX_CLK_BRG | RX_CLK_RTXC_PIN | TRXC_IS_OUTPUT | TRXC_OUT_BRG, WR12, 0x7e, /*time constant-low byte 19.2K bps*/ WR13, 0x00, /*time constant-high byte */ WR14, BRG_SOURCE_PCLK | DPLL_NULL, WR14, BRG_SOURCE_PCLK | DPLL_NULL, WR14, BRG_SOURCE_PCLK | DPLL_NULL, WR14, BRG_ENABLE | BRG_SOURCE_PCLK | DPLL_NULL, /* ENABLES */ WR3, RX_8_BITS | SYNC_CHAR_LOAD_INHIBIT | RX_ENABLE | ENTER_HUNT_MODE, /* vsg */ WR5, TX_8_BITS | CRC_16 | TX_ENABLE, WR0, RESET_TX_CRC, WR0, ERROR_RESET, WR1, WAIT_DMA_DISABLE | INT_DISABLE, WR15, NO_EXT_STAT_INT, /*INTERRUPT*/ WR0, RESET_EXT_STATUS_INT, WR0, RESET_EXT_STATUS_INT, WR1, WAIT_DMA_DISABLE | INT_DISABLE, WR9, MI_DISABLE }; /*******************************************************************/ /* end of init table, adjust variable PRAM_COUNT after modifying */ /*******************************************************************/ /*******************************************************************/ /* Function Prototypes */ /*******************************************************************/ int main(void); void PrintBuffer( void ); void PrintChar( char c ); static void SCCB_TxBufferEmpty (void); static void SCCB_ExtStatChange (void); static void SCCB_RxCharAvail (void); static void SCCB_SpRxCondition (void); static void SCCA_TxBufferEmpty (void); static void SCCA_ExtStatChange (void); static void SCCA_RxCharAvail (void); static void SCCA_SpRxCondition (void); void INTERRUPT isr(void); /*******************************************************************/ unsigned int head = 0; /* App. Receive Buffer Pointer */ unsigned int tail = 0; /* Int. Receive Buffer Pointer */ unsigned char RX_BUFFER[MAX_BUFFER]; unsigned int i; int ESCC = 0; unsigned int Active = 0; unsigned long CRC_ERROR_CNT = 0; unsigned long OVERRUN_CNT = 0; unsigned long PARITY_CNT = 0; unsigned long RX_FRAME_CNT = 0; unsigned long TX_FRAME_CNT = 0; unsigned long EOF_CNT = 0; /*******************************************************************/ int main(void) { void FAR *p; /* far void ptr*/ void (INTERRUPT *fp)(void); /* far void function ptr */ unsigned char c = 0; /*******************************************************************/ /* Verify Address of SCC (85x30) */ /*******************************************************************/ SCCout(PORT, WR2,0x55); /*write to WR2*/ if (SCCin(PORT, RR2)!=0x55) /*read back RR2*/ { printf("\nError: Device not found at address %x HEX.\n",PORT); return(1); /*return code 1 for ERROR*/ } else { printf("\nDevice verified at address %x HEX.\n",PORT); } /*******************************************************************/ /* Initialize ACB card */ /*******************************************************************/ SCCout(PORT, WR9, FORCE_HW_RESET); /*channel reset A and B*/ /*******************************************************************/ /* Test for ESCC (85230) */ /*******************************************************************/ SCCout(PORT, WR15, WR7P_ACCESS); c = SCCin(PORT, RR15); if(c & 0x01) { SCCout(PORT, WR15, 0x00); c = SCCin(PORT, RR15); if((c & 0x01) == 0) ESCC = 1; } if( ESCC ) /* 85230 specific actions */ { printf("Detected an 85230.\n"); SCCout(PORT, WR15, WR7P_ACCESS); SCCout(PORT, WR7_PRIME, EX_READ_ENABLE ); SCCout(PORT, WR15, 0x00); } else { printf("Detected an 8530.\n"); SCCout(PORT, WR15, 0x00); } p = &init[0]; SCCInitEx(PORT ,p ,PRAM_COUNT); /*Initialize ACB */ /*******************************************************************/ /* Terminal */ /*******************************************************************/ printf("Type on the keyboard to send characters, press Esc to end the\n" \ "program and display the buffer contents.\n"); printf("\n"); /* For ACB-VI un-comment this line to enable on-board interrupts */ /* OUT(PORT+4, 0x40); */ SaveIRQMask(); /* Save the IRQ Mask*/ fp = isr; IRQSetupEx(IRQ ,fp); /*Save/Replace Interrupt Vector, etc. */ SCCout(PORT ,WR1 ,RX_INT_ALL_CHAR_SP_COND); /*Interrupt on all Rx Char*/ SCCout(PORT ,WR9 , MI_ENABLE); /*Master Interrupt Enable ON*/ do { if (KBHIT()) { c = getch(); if (c != ESC) { OUT(PORT, STX); /* Start of Text */ while (!(SCCin(PORT, RR0) & TX_BUFFER_EMPTY)); OUT(PORT, c); /* write character to data port */ while (!(SCCin(PORT, RR0) & TX_BUFFER_EMPTY)); OUT(PORT, ETX); /* End of Text or ETB*/ while (!(SCCin(PORT, RR0) & TX_BUFFER_EMPTY)); TX_FRAME_CNT++; if( ECHO) PrintChar(c); } } } while (c != ESC); PrintBuffer(); SCCout(PORT ,WR9 ,MI_DISABLE); /*Master Interrupt Enable OFF*/ SCCout(PORT ,WR1 ,INT_DISABLE); /*All Interrupt conditions OFF*/ IRQUnsetup(IRQ); /*Restore Interrupt Vector, etc. */ ReturnIRQMask(); /*Restore IRQ Mask */ printf("\n"); /* new line after buffer chars */ if(RX_FRAME_CNT) printf("Frames received: %lu\n", RX_FRAME_CNT); if(TX_FRAME_CNT) printf("Frames transmitted: %lu\n", TX_FRAME_CNT); if(EOF_CNT) printf("EOF ints.: %lu\n", EOF_CNT); if(CRC_ERROR_CNT) printf("CRC errors: %lu\n", CRC_ERROR_CNT); if(PARITY_CNT) printf("Parity errors: %lu\n", PARITY_CNT); if(OVERRUN_CNT) printf("Overrun errors: %lu\n", OVERRUN_CNT); return(0); } /*******************************************************************/ /* Print Characters in Rx Buffer */ /*******************************************************************/ void PrintBuffer( void ) { while( head != tail ) { if( RX_BUFFER[head] == CR) printf("\n"); else printf("%c", RX_BUFFER[head]); /* Print character */ head++; if ( head > MAX_BUFFER ) head = 0; } } /*******************************************************************/ /* Print Single Character */ /*******************************************************************/ void PrintChar( char c ) { if( c == CR) printf("\n"); else printf("%c", c); /* Print character */ } /*******************************************************************/ /* Interrupt Service Routine (ISR) */ /* This Routine is called when an interrupt is generated by the */ /* ACB adapter */ /*******************************************************************/ void INTERRUPT isr(void) { unsigned char isr_ptr, counter=0; static void (*sccisr[8])(void) = { SCCB_TxBufferEmpty, /* This is an array of routines */ SCCB_ExtStatChange, /* that are called when an */ SCCB_RxCharAvail, /* interrupt is pending on the */ SCCB_SpRxCondition, /* 85x30. */ SCCA_TxBufferEmpty, SCCA_ExtStatChange, SCCA_RxCharAvail, SCCA_SpRxCondition, }; while (SCCin(PORT, RR3)) /* While Interrupt is Pending*/ { isr_ptr = SCCin(PORT+2, RR2); /* Read Register 2 on Ch B */ isr_ptr >>= 1; /* Adjust interrupt pointer */ (*sccisr[isr_ptr])(); /* Call isr sub routine */ counter++; if (counter > 200) /* Time out just in case something*/ { break; /* goes wrong. */ } } counter = 0; /* Reset Time out counter */ #if (IRQ > 7) OUT(0xa0 ,0x20); /* AT PIC EOI */ #endif OUT(0x20, 0x20); /* XT PIC EOI */ } /*******************************************************************/ /* SCCB_TxBufferEmpty : called from ISR */ /* This routine is called when a Transmit Buffer Empty */ /* interrupt is pending on channel B of the SCC */ /*******************************************************************/ static void SCCB_TxBufferEmpty (void) { } /*******************************************************************/ /* SCCB_ExtStatChange : called from ISR */ /* This routine is called when a External Status Change */ /* interrupt is pending on channel B of the SCC */ /*******************************************************************/ static void SCCB_ExtStatChange (void) { } /*******************************************************************/ /* SCCB_RxCharAvail : called from ISR */ /* This routine will read all characters on channel B of the SCC */ /* at interrupt time */ /*******************************************************************/ static void SCCB_RxCharAvail (void) { } /*******************************************************************/ /* SCCB_SpRxCondition : called from ISR */ /* This routine is called when a Receive Special Condition */ /* interrupt is pending on channel B of the SCC */ /*******************************************************************/ static void SCCB_SpRxCondition (void) { } /*******************************************************************/ /* SCCA_TxBufferEmpty : called from ISR */ /* This routine is called when a Transmit Buffer Empty */ /* interrupt is pending on channel A of the SCC */ /*******************************************************************/ static void SCCA_TxBufferEmpty (void) { } /*******************************************************************/ /* SCCA_ExtStatChange : called from ISR */ /* This routine is called when a External Status Change */ /* interrupt is pending on channel A of the SCC */ /*******************************************************************/ static void SCCA_ExtStatChange (void) { } /*******************************************************************/ /* SCCA_RxCharAvail : called from ISR */ /* This routine will read all characters on channel A of the SCC */ /* at interrupt time */ /*******************************************************************/ static void SCCA_RxCharAvail (void) { unsigned char x, y; while ( RX_CHAR_AVAIL & (x = (SCCin(PORT, RR0)))) { y = (unsigned char) IN(PORT); /* Read Character */ switch(y) { case STX: Active = 1; break; case ETB: case ETX: Active = 0; RX_FRAME_CNT++; SCCout( PORT,WR3, RX_8_BITS | SYNC_CHAR_LOAD_INHIBIT | RX_ENABLE | ENTER_HUNT_MODE); break; default: if (!Active) { /* vsg - re-enter hunt mode if idle sync. broken */ /* program would quit receiving if int3 was stopped */ /* and restarted on other PC. - i.e. broken sync. idle */ SCCout( PORT,WR3, RX_8_BITS | SYNC_CHAR_LOAD_INHIBIT | RX_ENABLE | ENTER_HUNT_MODE); break; } if (tail < MAX_BUFFER) /* if there is room in buffer */ { RX_BUFFER[tail] = y; /* put char in buffer */ tail++; /* inc buffer ptr */ } else /* if there is no room in the */ { tail = 0; /* wrap arround to the start */ RX_BUFFER[tail] = y; /* of the buffer */ tail++; } SCCout(PORT, WR0, ENABLE_INT_NEXT_RX_CHAR); break; } /* end switch case */ } } /*******************************************************************/ /* SCCA_SpRxCondition : called from ISR */ /* This routine is called when a Receive Special Condition */ /* interrupt is pending on channel A of the SCC */ /*******************************************************************/ static void SCCA_SpRxCondition (void) { unsigned char c; c = SCCin(PORT, RR1); c &= ( END_OF_FRAME | CRC_FRAMING_ERROR | RX_OVERRUN_ERROR | PARITY_ERROR); if (c & END_OF_FRAME) { SCCout(PORT, WR0, ERROR_RESET); EOF_CNT++; } if (c & CRC_FRAMING_ERROR) { SCCout(PORT, WR0, ERROR_RESET); CRC_ERROR_CNT++; } if (c & RX_OVERRUN_ERROR) { SCCout(PORT, WR0, ERROR_RESET); OVERRUN_CNT++; } if (c & PARITY_ERROR) { SCCout(PORT, WR0, ERROR_RESET); PARITY_CNT++; } SCCout(PORT, WR0, RESET_HIGHEST_IUS); SCCout(PORT, WR0, RESET_RX_CRC); SCCout(PORT, WR0, ENABLE_INT_NEXT_RX_CHAR); } /*******************************************************************/ /* End of File */ /*******************************************************************/