From 01a12fdad10b5995495e1a4236fdfb1a583979ab Mon Sep 17 00:00:00 2001 From: Joe Zhao Date: Fri, 16 May 2014 13:48:41 +0800 Subject: First Commit --- rs422lib/rsbus.c | 201 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 rs422lib/rsbus.c (limited to 'rs422lib/rsbus.c') diff --git a/rs422lib/rsbus.c b/rs422lib/rsbus.c new file mode 100644 index 0000000..705736f --- /dev/null +++ b/rs422lib/rsbus.c @@ -0,0 +1,201 @@ +/* + * rsbus.c + * + * Created on: 2014-4-26 + * Author: Tuowen + */ +#include "rsbus.h" +#include "sysctl.h" + +#define SYSRET (0xF0) +#define INSREP (0x0F) + +unsigned char rs_rxbuf[RSMAX]; +unsigned char len; +unsigned char pch; +unsigned char ret; +rshdlr rxhdlr; +enum rs_stat{REST,ST,ADDR,READ,DISCARD,ED,DED}; +enum rs_stat rs_st=REST; + +unsigned char rs_tx[12]={STBIT1,0,RSADDR,MACTYPE,0,0,0,0,0,0,0,0}; +unsigned char tx_len; +unsigned char tx_pos; + +#pragma vector=USCIAB0TX_VECTOR +__interrupt void USCI0TX_ISR(void) +{ + if (tx_pos == tx_len) // TX over? + { + UC0IE &= ~UCA0TXIE; // Disable USCI_A0 TX interrupt + RSOUT &= ~(RSPIN); + } + else + UCA0TXBUF = rs_tx[tx_pos++]; // TX next character +} + +#pragma vector=USCIAB0RX_VECTOR +__interrupt void rsbus_rx(void) +{ + //IFG2&=(~UCA0RXIFG); + int dat; + dat=UCA0RXBUF; + /************ Simple State Machine *************/ + switch (rs_st) + { + case REST: + rs_st=(dat==STBIT0)?ST:REST; + break; + case ST: + rs_st=(dat==STBIT1)?ADDR:REST; + break; + case ADDR: + if (dat==RSADDR) + { + rs_st=READ; + len=0; + pch=RSADDR; + } + else + rs_st=DISCARD; + break; + case READ: + rs_rxbuf[len++]=dat; + pch^=dat; + if (dat==EDBIT0) + rs_st=ED; + if (len>=RSMAX) + rs_st=REST; + break; + case DISCARD: + if (dat==EDBIT0) + rs_st=DED; + break; + case DED: + if (dat==EDBIT1) + rs_st=REST; + else + rs_st=DISCARD; + break; + case ED: + if (dat==EDBIT1) + { + rs_st=REST; + --len; + pch^=EDBIT0; + if (pch==0) // Parity check passed + { + if (len<2) + { + ret=(SYSRET ^ MACTYPE); + SYSCALL_IRQ(RSSYSRET); // RETURN machine type + } + else + SYSCALL_IRQ(RSSYSBIT); // SYSCTL call happened here!!! + } + else + { + ret=(SYSRET ^ INSREP); + SYSCALL_IRQ(RSSYSRET); // RETURN machine type + } + } + else + { + rs_rxbuf[len++]=dat; + pch^=dat; + rs_st=READ; + if (len>=RSMAX) + rs_st=REST; + } + break; + } + /*//This is a repeater + if (IFG2&UCA0TXIFG) + UCA0TXBUF=dat;*/ +} + +void rsbus_w(int addr,unsigned char* buf,unsigned int len) +{ + unsigned int i; + if (len>4) + return; + RSOUT |= RSPIN; + tx_len=len+7; + unsigned int parity=addr^MACTYPE^RSADDR; + rs_tx[1]=addr; + for (i=0;i Low as DEFAULT + /******************* SYSCTL INIT *************************/ + rxhdlr=hdlr; + sysctl_reghdlr(RSSYSBIT,&rsbus_syscall); + sysctl_reghdlr(RSSYSRET,&rsbus_ret); +} -- cgit v1.2.3-70-g09d2