head 4.4; access ; symbols ; locks oasisa:4.4; strict; comment @ * @; 4.4 date 2001.06.19.12.14.10; author oasisa; state Exp; branches ; next ; desc @New Repository; 6/19/2001 (klh) @ 4.4 log @New Repository; 6/19/2001 (klh) @ text @/****************************************************************************/ /* Copyright 1991 MBARI */ /****************************************************************************/ /* $Header: io.c,v 1.1 2001/06/19 11:44:01 oasisa Exp $ */ /* Summary : I/O and serial comm support for OASIS mooring controller */ /* Filename : io.c */ /* Author : Robert Herlien (rah) */ /* Project : OASIS Mooring Controller */ /* $Revision: 1.1 $ */ /* Created : 02/06/91 */ /* */ /* MBARI provides this documentation and code "as is", with no warranty, */ /* express or implied, of its quality or consistency. It is provided without*/ /* support and without obligation on the part of the Monterey Bay Aquarium */ /* Research Institute to assist in its use, correction, modification, or */ /* enhancement. This information should not be published or distributed to */ /* third parties without specific written permission from MBARI. */ /* */ /* Archived : */ /****************************************************************************/ /* Modification History: */ /* 06feb91 rah - created */ /* $Log: io.c,v $ * Revision 1.1 2001/06/19 11:44:01 11:44:01 oasisa (Oasis users) * Initial revision * * Revision 4.3 99/06/16 10:21:32 10:21:32 bobh (Bob Herlien) * Mar/May '99 Deployments of M3/M2 * * Revision 3.7 97/07/23 11:18:03 11:18:03 bobh (Bob Herlien) * July '97 M1 deployment, new shutter code * * Revision 3.5 96/07/17 13:01:23 13:01:23 bobh (Bob Herlien) * July '96 deployment of M2 with ARGOS code * * Revision 3.4 96/06/18 15:24:13 15:24:13 bobh (Bob Herlien) * June '96 deployment of M1 * * Revision 3.3 95/04/13 13:46:50 13:46:50 hebo (Bob Herlien) * Drifter Deployment for Coop (flip) cruise * * Revision 3.2 95/04/11 14:03:24 14:03:24 hebo (Bob Herlien) * Drifter Deployment on IronEx * * Revision 3.1 95/03/09 19:30:53 19:30:53 hebo (Bob Herlien) * March '95 Deployment of M1A * * Revision 3.0 95/02/21 18:42:39 18:42:39 hebo (Bob Herlien) * February '95 Deployment * * Revision 2.0 92/08/21 14:45:15 14:45:15 hebo (Bob Herlien) * August 1992 deployment * * Revision 1.3 92/03/05 14:23:05 14:23:05 hebo (Bob Herlien 408-647-3748) * New defaults, restart check, perm power stuff, analog command, gps changes * */ /****************************************************************************/ #include /* MBARI type definitions */ #include /* MBARI constants */ #include /* OASIS controller definitions */ #include /* OASIS I/O definitions */ #include /* WATCHDOG definition */ #include <80c196.h> /* 80196 Register mapping */ #include /* OASIS task definitions */ #define RTC_ALARM_INT_BIT 0x2 /* Alarm bit in RTC_STATUS reg */ /********************************/ /* External Functions */ /********************************/ Extern Void ring_init( Ring *ring_ptr, Byte *buffer, Nat16 size ); Extern Int16 ring_put( Ring *ring_ptr, Byte byte ); Extern Int16 ring_get( Ring *ring_ptr ); Extern Int16 ring_getn( Ring *ring_ptr, Byte *p, Nat16 n ); Extern Int16 ring_entries( Ring *ring_ptr ); Extern Void ring_flush( Ring *ring_ptr ); Extern Word clk_status( Void ); #ifdef ALLOW_PERM_WAKE Extern MBool GPS_KEEPALIVE; #endif /********************************/ /* External Data */ /********************************/ Extern Reg Int16 task_tick; /* Ticks since last dispatch() */ Extern Reg MBool ext_wake; /* TRUE if woke by /wake pin */ Extern Reg TimeOfDay tod; /* Current time in TimeOfDay format */ Extern Reg Byte ser_stat; /* Copy of sp_stat register */ Extern Reg Byte uarta_stat; /* Copy of uarta_usr */ Extern Reg Byte uartb_stat; /* Copy of uartb_usr */ Extern Nat16 xoff_tmout; /* Timeout for xoff */ /********************************/ /* Global Data */ /********************************/ Global Int16 wdcnt; /* Countdown counter for watchdog */ Global Nat16 pwr_perm; /* Devices to leave powered on */ Global Nat16 iopwrbits; /* PIA A bits to control power */ Global Nat16 randSeed; /* Seed for random number generator */ Global Reg Word error; /* Error vector */ Global Reg Nat16 tick; /* 10 ms ticker */ Global Reg Byte ioctrl; /* Copy of oasis_ctrl */ Global Reg Byte port1_copy; /* Copy of Port 1 bits */ Global Reg Byte ios1_copy; /* Copy of IOS1 register */ Global Reg Byte io_wakebits; /* Copy of wakeup bits */ Global Reg Byte tx_status[NSER_PORTS]; /* UART Transmitter status */ Global Reg Byte do_xon[NSER_PORTS]; /* TRUE to do XON/XOFF */ Global Reg Byte modem_ctrl[NSER_PORTS]; /* Modem control bits */ #define XMITOFF 1 /* tx_status bit shows no data */ #define XOFFSTS 2 /* tx_status bit shows XOFF */ Global Reg Byte xoff_timer[NSER_PORTS]; /* To time out XOFF status */ Global Ring tx_ring[NSER_PORTS]; /* Serial IO transmit data structs */ Global Ring rx_ring[NSER_PORTS]; /* Serial IO receive data structs */ /********************************/ /* Module Local Data */ /********************************/ MLocal Byte tx_buf[NSER_PORTS][XMITRING_SIZE]; /* Serial data xmit bufs */ MLocal Byte rx_buf[NSER_PORTS][RCVRING_SIZE]; /* Serial data rcv bufs */ MLocal Word relay0, relay1; /* Relay State, 2 bits/relay: */ /* 10 = reset, 01 = set, 11 = unknwn*/ MLocal Semaphore relay_sem; /* Mutex semaphore for relays */ const Byte uart_ucr[] = {0x2e, 0x20, 0x22, 0x2e, 0x3e, 0x30, 0x32, 0x3e, 0x2f, 0x21, 0x23, 0x2f, 0x3f, 0x31, 0x33, 0x3f}; volatile Byte * const ser_data[] = { &sbuf, &uarta_data, &uartb_data }; /* Baud rate constants for CPU serial port and 82C52 Uarts */ /* for baud rates of 150, 300, 1200, 2400, 4800, 9600, 19200, 38400 baud */ const Nat16 cpu_baud[] = {0x8fff, 0x87ff, 0x81ff, 0x80ff, 0x807f, 0x803f, 0x801f, 0x800f}; const Byte uart_baud[] = {0xbe, 0xb2, 0xa6, 0xa2, 0x96, 0x8e, 0x86, 0x82}; /************************************************************************/ /* Interrupt Service Routine Declarations */ /************************************************************************/ #pragma interrupt( bad_int=0, bad_int=1, bad_int=2, bad_int=3, hsi0_int=4 ) #pragma interrupt( swt_int=5, bad_int=6, bad_int=7, bad_int=8, bad_int=9 ) /************************************************************************/ /* Function : bad_int */ /* Purpose : Spurious Interrupt handler */ /* Inputs : None */ /* Outputs : None */ /************************************************************************/ Void bad_int( Void ) { error |= INT_ERR; } /* bad_int() */ /************************************************************************/ /* Function : swt_int */ /* Purpose : Software Timer Interrupt handler */ /* Inputs : None */ /* Outputs : None */ /************************************************************************/ Void swt_int( Void ) { ios1_copy |= ios1; /* Get I/O status byte */ hso_command = HSO_SW_TIMER(0) | HSO_INT; /* Restart SW timer */ hso_time = timer1 + TICK; /* Set new timeout */ tick++; /* Increment global ticker */ task_tick++; /* Increment task delay ticker */ #ifdef WATCHDOG if ( wdcnt > 0 ) /* Watchdog code */ { /* If still have time on wd timeout*/ wdcnt -= WATCH_FACTOR; watchdog = 0x1e; /* ping the watchdog timer */ watchdog = 0xe1; /* If not, we won't ping watchdog */ } /* and system will reset */ #endif } /* swt_int() */ /************************************************************************/ /* Function : hsi0_int */ /* Purpose : Interrupt Handler for HSI.0 interrupt pin */ /* Inputs : None */ /* Outputs : None */ /* Comment : HSI.0 services the ints from 68HC68 and the PIAs */ /* However, the PIA's don't generate interrupts */ /************************************************************************/ Void hsi0_int( Void ) { if ( ioport2 & EXTWAKE_BIT ) ext_wake = TRUE; /* If /EXT_WAKE, set Boolean */ } /* hsi0_int() */ /************************************************************************/ /* Function : xmit_chr */ /* Purpose : Send one char to serial port */ /* Inputs : Serial port to send data to */ /* Outputs : Character sent, or ERROR if ring buffer empty */ /* Comments : Used by xmit_int(), enbl_xmit() */ /************************************************************************/ Int16 xmit_chr( Reg Nat16 port ) { Reg Int16 tx_byte; if ( (tx_byte = ring_get(&tx_ring[port])) == ERROR ) tx_status[port] |= XMITOFF; /* If no bytes, turn off xmit sts*/ else /* send next byte from xmit fifo */ *ser_data[port] = (Byte)tx_byte; return( tx_byte ); } /* xmit_chr() */ /************************************************************************/ /* Function : enbl_xmit */ /* Purpose : Enable transmitter on a serial port */ /* Input : Port number */ /* Output : None */ /************************************************************************/ Void enbl_xmit( Nat16 port ) { if ( tx_status[port] & XOFFSTS ) /* If XOFF'd, return */ return; tx_status[port] = 0; /* Show tx enabled */ switch( port ) { case CPU_SER: /* 80C196 serial port */ imask1 = RCV | EXT_INT; /* Turn off Tx Ints */ ser_stat |= sp_stat; /* Get serial status */ if ( ser_stat & SER_TXE ) /* If both tx bufs empty*/ if ( xmit_chr(CPU_SER) != ERROR ) /* send a char */ ser_stat &= ~SER_TXE; /* and clear TXE */ if ( ser_stat & SER_TI ) /* If xmit buf avail */ if ( xmit_chr(CPU_SER) != ERROR ) /* send char */ ser_stat &= ~SER_TI; /* and clear TI */ imask1 = XMIT | RCV | EXT_INT; /* Reenable ints */ break; case UARTA: /* UART A */ oasis_ctrl = ioctrl & ~UARTA_INT; /* Turn off Tx Ints */ uarta_stat |= uarta_usr; /* Get serial status */ if ( uarta_stat & XMIT_RDY ) /* If xmit buf avail, */ if ( xmit_chr(UARTA) != ERROR ) /* send char */ uarta_stat &= ~(XMIT_RDY | XMIT_DONE); ioctrl |= UARTA_INT; /* Allow Tx ints from UARTA*/ break; case UARTB: /* UART B */ oasis_ctrl = ioctrl & ~UARTB_INT; /* Turn off Tx Ints */ uartb_stat |= uartb_usr; /* Get serial status */ if ( uartb_stat & XMIT_RDY ) /* If xmit buf avail, */ if ( xmit_chr(UARTB) != ERROR ) /* send char */ uartb_stat &= ~(XMIT_RDY | XMIT_DONE); ioctrl |= UARTB_INT; /* Allow Tx ints from UARTB*/ break; } oasis_ctrl = ioctrl; /* Output control byte */ } /* enbl_xmit() */ /************************************************************************/ /* Function : ioCheckXoffStatus */ /* Purpose : Check if any port has timed out on XOFF */ /* Input : None */ /* Output : None */ /* Comment : Called once/second from oasis task main loop */ /************************************************************************/ Void ioCheckXoffStatus( Void ) { Reg Nat16 i; for ( i = 0; i < NSER_PORTS; i++ ) /* XOFF timeouts */ if ( tx_status[i] & XOFFSTS ) /* If port is XOFF'd */ if ( ++xoff_timer[i] > xoff_tmout ) { tx_status[i] &= ~XOFFSTS; enbl_xmit(i); } } /* ioCheckXoffStatus() */ /************************************************************************/ /* Function : ser_init */ /* Purpose : Initialize one serial port */ /* Inputs : Serial port to init (0 - 2) */ /* Initialization word */ /* Bit 12 = TTL/RS-232 mode: 0 = RS-232, 1 = TTL */ /* NOTE - UARTs A & B only! Can't do TTL on CPU ser*/ /* Bits 10-11 = Newline mode - what to send on \n to output:*/ /* 00 = \n, 01 = \r\n, 02 = \r, 03 = none */ /* Bit 9 = Echo mode: 1 to do local echo, 0 for none */ /* Bit 8 = Flow control: 1 for XON/XOFF, 0 for none */ /* Bit 7 = Stop bits: 0 for 1 stop bit, 1 for 2 stop bits */ /* Bit 6 = Character len: 0 for 7 bits, 1 for 8 bits */ /* Bits 4-5 = Parity: 00 = none, 01 = Even, 10 = odd, 11 rsvd*/ /* Bits 0-3 = Baud rate: 0 = 150, 1 = 300, 2 = 1200 */ /* 3 = 2400, 4 = 4800, 5 = 9600, 6 = 19200 */ /* 7 = 38400, 8 - 15 reserved */ /* Outputs : MBool, TRUE if OK */ /************************************************************************/ Void ser_init( Nat16 port, Nat16 mode ) { Reg WordByte ubaud; Reg Word umode, baud; Reg Byte ucrbyte; baud = mode & BAUD_MASK; /* Save baud rate */ umode = mode & PTY_LEN_STOP; /* Save mode */ ucrbyte = uart_ucr[umode >> 4]; /* Get ucr byte for UARTs */ do_xon[port] = (mode & FLOW) ? TRUE : FALSE; switch( port ) { case CPU_SER: /* 80C196 serial port */ imask1 = EXT_INT; if ( umode == (NO_PTY | BIT8 | STOP1) ) modem_ctrl[CPU_SER]= SER_MODE(1) | SER_REN; /* Set serial mode 1 */ else if ( umode == (EVEN_PTY | BIT7 | STOP1) ) modem_ctrl[CPU_SER] = SER_MODE(1) | SER_REN | SER_PEN; else /* 80196 UART can only do no parity*/ return; /* 8 bit or even parity 7 bit */ sp_con = modem_ctrl[CPU_SER]; ubaud.wb_word = cpu_baud[baud]; /* Set CPU serial baud rate */ baud_rate = ubaud.wb_byte[0]; baud_rate = ubaud.wb_byte[1]; ser_stat = sp_stat; /* Read status reg to clear it */ ser_stat = SER_TI | SER_TXE; /* Init status, turn on Tx avail*/ break; case UARTA: /* UART A */ imask1 = XMIT | RCV; /* Disable external interrupts */ ioctrl &= ~UARTA_INT; /* Turn off xmit int */ uarta_brsr = uart_baud[baud]; /* Set uart A baud rate */ uarta_ucr = ucrbyte; /* Set up parity, len, stop bits*/ modem_ctrl[UARTA] = (UART_RCVEN | ((mode & SER_TTL) ? 0 : DTR)); /* Rcv enbl, DTR switches RS-232*/ uarta_mcr = modem_ctrl[UARTA]; /* Put out modem control bits */ uarta_stat = uarta_usr; /* Read USR to clear it */ uarta_stat = XMIT_RDY | XMIT_DONE; break; case UARTB: /* UART B */ imask1 = XMIT | RCV; /* Disable external interrupts */ ioctrl &= ~UARTB_INT; /* Turn off xmit int */ uartb_brsr = uart_baud[baud]; /* Set uart B baud rate */ uartb_ucr = ucrbyte; /* Set up parity, len, stop bits*/ modem_ctrl[UARTB] = (UART_RCVEN | ((mode & SER_TTL) ? 0 : DTR)); /* Rcv enbl, DTR switches RS-232*/ uartb_mcr = modem_ctrl[UARTB]; /* Put out modem control bits */ uartb_stat = uartb_usr; /* Read USR to clear it */ uartb_stat = XMIT_RDY | XMIT_DONE; break; default: /* Bad serial port number */ return; } ucrbyte = *ser_data[port]; /* Read data reg to clear it */ oasis_ctrl = ioctrl; /* Output control byte */ tx_status[port] = XMITOFF; /* Turn off xmit status */ /* Set up transmit & receive buffers*/ ring_init(&tx_ring[port], tx_buf[port], XMITRING_SIZE); ring_init(&rx_ring[port], rx_buf[port], RCVRING_SIZE); imask1 = XMIT | RCV | EXT_INT; /* Allow interrupts */ } /* ser_init() */ /************************************************************************/ /* Function : ser_putc */ /* Purpose : Write one character to serial port */ /* Inputs : Port number, character */ /* Output : MBool, TRUE if character sent */ /************************************************************************/ MBool ser_putc( Nat16 port, Byte byte ) { if ( ring_put(&tx_ring[port], byte) == 0 ) return( FALSE ); if ( tx_status[port] & XMITOFF ) enbl_xmit( port ); return( TRUE ); } /* ser_putc() */ /************************************************************************/ /* Function : ser_getc */ /* Purpose : Read one character from serial port */ /* Inputs : Port number */ /* Output : Character, or ERROR if none */ /************************************************************************/ Int16 ser_getc( Nat16 port ) { return( ring_get(&rx_ring[port]) ); } /* ser_getc() */ /************************************************************************/ /* Function : ser_getn */ /* Purpose : Read N characters from serial port */ /* Inputs : Port number, ptr to put chars, number of chars to get */ /* Output : Number of chars read */ /************************************************************************/ Int16 ser_getn( Nat16 port, char *p, Int16 nchars ) { return( ring_getn(&rx_ring[port], (Byte *)p, nchars) ); } /* ser_getn() */ /************************************************************************/ /* Function : ser_sndsts */ /* Purpose : Get number characters left to send on serial port */ /* Inputs : Port number */ /* Output : Number characters left to send */ /* Comments : If ring buffer is empty, checks UART to see if it's */ /* still sending a character. This is to ensure that the */ /* last byte is sent before this function returns a 0. */ /************************************************************************/ Int16 ser_sndsts( Nat16 port ) { Int16 i; if ( (i = ring_entries(&tx_ring[port])) > 0 ) return( i ); asm pushf; switch ( port ) { case CPU_SER: /* 80C196 serial port */ ser_stat |= sp_stat; /* Get serial status */ i = ser_stat & SER_TXE; break; case UARTA: /* UART A */ uarta_stat |= uarta_usr; /* Get serial status */ i = uarta_stat & XMIT_DONE; break; case UARTB: /* UART B */ uartb_stat |= uartb_usr; /* Get serial status */ i = uartb_stat & XMIT_DONE; break; } asm popf; return( i ? 0 : 1 ); } /* ser_sndsts() */ /************************************************************************/ /* Function : ser_flush */ /* Purpose : Discard input on a serial line */ /* Inputs : Port number */ /* Output : None */ /************************************************************************/ Void ser_flush( Nat16 port ) { ring_flush( &rx_ring[port] ); } /* ser_flush() */ /************************************************************************/ /* Function : ser_break */ /* Purpose : Send 1000 ms break signal to a serial port */ /* Inputs : Port number */ /* Output : None */ /* Comment : Increased from 200 ms 2/11/2000 rah */ /* Added variable break period 7/5/00 klh */ /************************************************************************/ Void ser_break( Nat16 port, Int16 count ) { if ( count <= 0 ) count=TICKS_PER_SECOND; switch( port ) { case CPU_SER: ioc1 = IOC1_BRK; ioport2 = ~TXDBIT; /*task_delay( TICKS_PER_SECOND );*/ task_delay( count ); ioport2 = 0xff; ioc1 = IOC1; return; case UARTA: uarta_mcr = (modem_ctrl[UARTA] | UART_BRK); /*task_delay( TICKS_PER_SECOND );*/ task_delay( count ); uarta_mcr = modem_ctrl[UARTA]; return; case UARTB: uartb_mcr = (modem_ctrl[UARTB] | UART_BRK); /*task_delay( TICKS_PER_SECOND );*/ task_delay( count ); uartb_mcr = modem_ctrl[UARTB]; return; } } /* ser_break() */ /************************************************************************/ /* Function : io_atod */ /* Purpose : A/D Conversion Routine */ /* Inputs : A/D Port number */ /* Outputs : 10 bit A/D value, or ERROR */ /************************************************************************/ Nat16 io_atod( Nat16 channel ) { Reg WordByte value; /* Union for byte to word*/ Reg Byte i; ad_command = AD_CHAN(channel) | AD_GO; /* Start A/D */ for ( i = 10; i && (ad_result_lo & AD_NRDY); i-- ) /* Wait for A/D done*/ ; /* Should take 91 states*/ value.wb_byte[1] = ad_result_hi; /* Get high 8 bits */ value.wb_byte[0] = ad_result_lo; /* Get low 2 bits */ return( value.wb_word >> 6 ); /* Return normalized value*/ } /* io_atod() */ /************************************************************************/ /* Function : oneRelayBank */ /* Purpose : Select Relay state for one serial mux */ /* Inputs : Ptr to current state, relay select vector */ /* Outputs : Word to put out */ /* Comments : See io_relay */ /************************************************************************/ Word oneRelayBank( Word *curState, Word select ) { Reg Word state, reset_bits, set_bits, new_bits; state = *curState; set_bits = (state >> 1) & 0x5555 & select; reset_bits = (state << 1) & 0xaaaa & select; new_bits = set_bits | reset_bits; *curState = state & ~((set_bits << 1) | (reset_bits >> 1)) | new_bits; return( new_bits ); } /* oneRelayBank() */ /************************************************************************/ /* Function : io_relay */ /* Purpose : Select Relay state for serial mux */ /* Inputs : Relay select vector */ /* Outputs : None */ /* Comments : Relay vector is a word containing 8 2-bit fields (one */ /* for each relay). For each 2-bit field, 00 = leave relay*/ /* in current state, 01 = set, 10 = reset, 11 is illegal */ /************************************************************************/ Void io_relay( Word select0, Word select1 ) { sem_take( &relay_sem ); relay0_enbl = oneRelayBank( &relay0, select0 ); #ifdef ROCKY relay1_enbl = oneRelayBank( &relay1, select1 ); #endif task_delay( TICKS_PER_SECOND/20 ); sem_give( &relay_sem ); } /* io_relay() */ /************************************************************************/ /* Function : io_power */ /* Purpose : Turn on/off power to selected instruments */ /* Inputs : Bit vector of instruments to turn on */ /* Outputs : None */ /************************************************************************/ Void io_power( Word pwrbits ) { #ifdef ROCKY iopwrbits = pwrbits; pwr_enbl = iopwrbits; #else io_wakebits &= ~PWR_STROBE; piaa_pdb = io_wakebits iopwrbits = pwrbits; piaa_pdc = (Byte)iopwrbits; piaa_pdb = io_wakebits | PWR_STROBE; piaa_pdb = io_wakebits; #endif } /* io_power() */ /************************************************************************/ /* Function : io_pwron */ /* Purpose : Turn on power to selected instruments */ /* Inputs : Bit vector of instruments to turn on */ /* Outputs : None */ /************************************************************************/ Void io_pwron( Word pwrbits ) { io_power( iopwrbits | pwrbits ); } /* io_pwron() */ /************************************************************************/ /* Function : io_pwroff */ /* Purpose : Turn off power to selected instruments */ /* Inputs : Bit vector of instruments to turn off */ /* Outputs : None */ /************************************************************************/ Void io_pwroff( Word pwrbits ) { io_power( iopwrbits & ~pwrbits ); } /* io_pwroff() */ /************************************************************************/ /* Function : io_init */ /* Purpose : Initialize I/O system */ /* Inputs : None */ /* Outputs : None */ /************************************************************************/ Void io_init( Void ) { Reg Nat16 i; wsr = 0; /* Register window 0 */ ioc0 = IOC0; /* Enbl HSI.0 enbl, 1-3 dsbl */ ioc1 = IOC1; /* TXT, EXTINT, PWM */ ioc2 = IOC2; /* Clear CAM, slow A/D clk */ ioctrl = UART_CLK | ANALOG_DSBL; /* Enable UART clock */ oasis_ctrl = ioctrl; /* Set up control byte */ port1_copy = PWM1 | PWM2 | RTC_SI; /* Init Port 1 */ ioport1 = port1_copy; ioport2 = 0xff; /* Init Port 2 */ /* TTL to UART A,B, no Tx Int */ piaa_cra = PIA_CR_NOHS; /* Set up PIA A */ piaa_crb = PIA_CR_NOHS; /* No handshake, no interrupts */ piaa_fsr = (Byte)0; /* Port C bits normal */ piaa_ddra = (Byte)0; /* Port A all inputs */ piaa_ddrb = (Byte)0xff; /* Port B all outputs */ piaa_pdb = (Byte)0; /* Output data all zeros */ io_wakebits = (Byte)0; /* Remember port B bits */ #ifdef ALLOW_PERM_WAKE /* For keeping GPS awake for test */ if (GPS_KEEPALIVE==TRUE) io_wakebits|=GPS_BIT; #endif piaa_ddrc = (Byte)0xff; /* Port C all outputs */ piaa_pdc = (Byte)0; /* Output data all zeros */ #ifdef ROCKY wakeport = (Byte)io_wakebits; /* Turn off all wakeups */ #endif piab_cra = PIA_CR_NOHS; /* Set up PIA B */ piab_crb = PIA_CR_NOHS; /* No handshake, no interrupts */ piab_fsr = (Byte)0; /* Port C bits normal */ piab_pda = (Byte)0; /* Output data all zeros */ piab_ddra = (Byte)0xff; /* Ports A, B, C all outputs */ piab_pdb = (Byte)0; /* Output data all zeros */ piab_ddrb = (Byte)0xff; piab_pdc = (Byte)0; /* Output data all zeros */ piab_ddrc = (Byte)0xff; sem_init( &relay_sem, 1 ); /* Init relay semaphore */ relay0 = relay1 = RELAYS_OFF; /* Init relay positions */ relay0_enbl = RELAYS_OFF; #ifdef ROCKY relay1_enbl = RELAYS_OFF; /* Init Rocky relays */ #endif for ( i = 0; i < NSER_PORTS; i++ ) /* Init all ser ports to 96,N,8,1 */ ser_init( i, (BAUD_9600 | NO_PTY | BIT8 | STOP1) ); tick = 0; /* Initialize 10 ms ticker */ wdcnt = WATCH_COUNT; /* Initialize software watchdog */ swt_int(); /* Start timer */ ext_wake = FALSE; /* Initialize ext_wake Boolean */ hsi0_int(); /* Check ext_wake status */ int_mask = SW_TIMER | HSI0; /* Allow timer, HSI.0 ints */ imask1 = XMIT | RCV | EXT_INT; /* Allow Tx, Rx, external ints */ io_power( pwr_perm ); /* Turn on perm powered instruments*/ asm ei; /* Enable interrupts */ while( tick < 2 ) /* Let the relays settle */ ; } /* io_init() */ /************************************************************************/ /* Function : io_term */ /* Purpose : Prepare I/O system for powerdown */ /* Inputs : None */ /* Outputs : None */ /************************************************************************/ Void io_term( Void ) { io_relay( RELAYS_OFF, RELAYS_OFF ); /* Open relays to serial ports */ io_power( pwr_perm ); /* Leave on the permanent pwr bits*/ int_mask = HSI0; /* Turn off timer ints */ wdcnt = WATCH_COUNT; /* Show we exited ok */ randSeed = timer1; } /* io_term() */ @