/* ****************SCI1.C******** Jonathan W. Valvano April 17, 2000 RS485 half-duplex multiport network Hardware: Adapt812 MC68HC812A4 SCI1 serial port RS-485 half-duplex network to other Adapt812s 6812 PS3/TXD1 connected to SP483 DI data in 6812 PS2/RXD1 connected to SP483 RO receive out 6812 PE6 connected to SP483 DE 1 enables transmission 6812 PE5 connected to SP483 RE 0 enables receiver SP483 A-A, B-B, ground-ground */ // bits in the SC1SR1 status register #define TBE 0x80 #define TC 0x40 #define RDF 0x20 void cycwait(unsigned int cycles){ TC5=TCNT+cycles; // number of 125ns cycles to wait TFLG1 = 0x20; // clear C5F while((TFLG1&0x20)==0){};} //-------------------------Start of InitSCI1------------------------ // Initialize Serial port SCI1 void SCI1Init(void){ SC1BDH=0; // 9600 BR=52 (MCLK=8MHz) clock SC1BDL=52; // BR=MCLK/(16*BaudRate) TSCR |=0x80; // TEN(enable) TIOS |= 0x20; // enable OC5 SC1CR1=0x12; /* bit value SC1CR1 meaning 7 0 LOOPS, no looping, normal 6 0 WOMS, normal high/low outputs 5 0 RSRC, not appliable with LOOPS=0 4 1 M, 1 start, 9 bit (8data+parity), 1 stop 3 0 WAKE, wake by idle (not applicable) 2 0 ILT, short idle time (not applicable) 1 1 PE, parity 0 0 PT, even parity type */ SC1CR2=0x0C; /* bit value SC1CR2 meaning 7 0 TIE, no transmit interrupts on TDRE 6 0 TCIE, no transmit interrupts on TC 5 0 RIE, no receive interrupts on RDRF 4 0 ILIE, no interrupts on idle 3 1 TE, enable transmitter 2 1 RE, enable receiver 1 0 RWU, no receiver wakeup 0 0 SBK, no send break */ DDRE = 0x60; // PE6,PE5 control RS485 chip // PE5=RE=0 enables RS485 receiver // PE6=TE=1 enables RS-485 transmitter PORTE=0x40; // TE=1, RE=0, enable RS485 transmitter } //-------------------------Start of SCI1InStatus-------------------------- // Checks if new input is ready, TRUE if new input is ready // Returns TRUE if a call to SCI1In will return right away int SCI1InStatus(void) { return(SC1SR1 & RDF);} //-------------------------Start of SCI1In------------------------ // Wait for new serial port input, return ASCII code for key typed char SCI1In(int *errPt){ // gadfly wait // returns by value the ASCII character from the RS485 network // returns by reference, 1-15 for errors, 0 for no error while ((SC1SR1 & RDF) == 0); (*errPt)=SC1SR1 & 0x0F; // Bit3=OR, Bit2=NF, Bit1=FE, Bit0=PF return(SC1DRL);} //-------------------------Start of SCI1Out------------------------ // output ASCII to RS485 channel, wait for echo, check for collision // receiver always enabled, transmitter always enabled int SCI1Out(char dataOut){ char echoIn,status; int error; // returns OK(0), COLLISION(1), TIMEOUT(2) or PARITYERROR(4) error=OK; // assume no errors SC1DRL = dataOut; // start transmission cycwait(10000); // 1.25msec (12 bit times) status=SC1SR1; if(status& RDF){ // should be ready, if not return as a timeout echoIn=SC1DRL; // capture echo, clear flags if (status & PF) error|=PARITYERROR; if(echoIn!=dataOut) // half-duplex, so outgoing should match incoming error|=COLLISION; // collision error, did not match } else error=TIMEOUT; // no response 1.25ms after sent return error;} //-------------------------Start of SCI1OutString------------------------ // Output String (NULL termination) int SCI1OutString(char *pt){ char letter; int error; error=0; while (letter=*pt++) error|=SCI1Out(letter); return error;}