/* * 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); }