summaryrefslogtreecommitdiff
path: root/rs422lib/rsbus.c
diff options
context:
space:
mode:
authorJoe Zhao <ztuowen@gmail.com>2014-05-23 15:36:51 +0800
committerJoe Zhao <ztuowen@gmail.com>2014-05-23 15:36:51 +0800
commit07d2ace8b4771e2ad48d4a9e6bf43a2022a25fac (patch)
tree8f76b7e3ce69ceb6d7822ec9aa8977a830d10c8d /rs422lib/rsbus.c
parentd9c0c179fc4636b8927dd2c8b2cb29d573094731 (diff)
downloadrsbus-07d2ace8b4771e2ad48d4a9e6bf43a2022a25fac.tar.gz
rsbus-07d2ace8b4771e2ad48d4a9e6bf43a2022a25fac.tar.bz2
rsbus-07d2ace8b4771e2ad48d4a9e6bf43a2022a25fac.zip
Added SYSSTOP & MSTATE macro
New example main.c
Diffstat (limited to 'rs422lib/rsbus.c')
-rw-r--r--rs422lib/rsbus.c364
1 files changed, 182 insertions, 182 deletions
diff --git a/rs422lib/rsbus.c b/rs422lib/rsbus.c
index c69a664..e0a18ec 100644
--- a/rs422lib/rsbus.c
+++ b/rs422lib/rsbus.c
@@ -1,182 +1,182 @@
-/*
- * rsbus.c
- *
- * Created on: 2014-4-26
- * Author: Tuowen
- */
-#include "rsbus.h"
-#include "sysctl.h"
-
-#define SYSRET (0xF0)
-#define INSREP (0x0F)
-
-// Maximum size of receive buffer
-#define RSMAX (20)
-
-#define CODE_LEN (6)
-
-unsigned char rs_rxbuf[RSMAX];
-unsigned char len;
-unsigned char pch;
-rshdlr rxhdlr;
-enum rs_stat{REST,ST,ADDR,READ,DISCARD,ED,DED};
-enum rs_stat rs_st=REST;
-
-unsigned char rs_tx[CODE_LEN+RS_MAX]={STBIT1,0,RSADDR,MACTYPE};
-volatile unsigned char tx_len;
-volatile unsigned char tx_pos=255;
-
-volatile unsigned char mac_stat[4]={0,0,0,0};
-
-// UART transmit routine
-#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);
- tx_pos = 255;
- }
- else
- UCA0TXBUF = rs_tx[tx_pos++]; // TX next character
-}
-
-// Inline send for ISR
-#pragma FUNC_ALWAYS_INLINE(rsbus_w_irq)
-static __inline void rsbus_w_irq(unsigned char* buf,unsigned int len)
-{
- unsigned int i;
- if (tx_pos < tx_len) // This shouldn't happen
- return; // Race condition
- RSOUT |= RSPIN;
- tx_len=len+7;
- unsigned int parity=MACTYPE^RSADDR;
- rs_tx[1]=0; // Useless addr spec
- for (i=0;i<len;++i)
- parity^=(rs_tx[4+i]=buf[i]);
- rs_tx[4+len]=parity;
- rs_tx[5+len]=EDBIT0;
- rs_tx[6+len]=EDBIT1;
- tx_pos=0;
- UCA0TXBUF=(STBIT0 & 0xff);
- UC0IE |= UCA0TXIE;
-}
-
-#pragma vector=USCIAB0RX_VECTOR
-__interrupt void rsbus_rx(void)
-{
- //IFG2&=(~UCA0RXIFG);
- unsigned char 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)
- rsbus_w_irq((unsigned char*)mac_stat,4); // RETURN CURRENT STATUS
- else
- SYSCALL_IRQ(RSSYSBIT); // SYSCTL call happened here!!!
- }
- else // Parity check failed
- {
- dat = SYSRET ^ INSREP; // RETURN REP
- rsbus_w_irq(&dat,1);
- }
- }
- else
- {
- rs_rxbuf[len++]=dat;
- pch^=dat;
- rs_st=READ;
- if (len>=RSMAX)
- rs_st=REST;
- }
- break;
- }
-}
-
-void rsbus_w(int addr,unsigned char* buf,unsigned int len)
-{
- while (tx_pos < tx_len) // This shouldn't happen
- __delay_cycles(100); // Race condition -> wait
- unsigned int i;
- if (len>RS_MAX)
- return;
- RSOUT |= RSPIN;
- tx_len=len+7;
- unsigned int parity=addr^MACTYPE^RSADDR;
- rs_tx[1]=addr; // Useless addr spec
- for (i=0;i<len;++i)
- parity^=(rs_tx[4+i]=buf[i]);
- rs_tx[4+len]=parity;
- rs_tx[5+len]=EDBIT0;
- rs_tx[6+len]=EDBIT1;
- tx_pos=0;
- UCA0TXBUF=(STBIT0 & 0xff);
- UC0IE |= UCA0TXIE;
-}
-
-void rsbus_syscall()
-{
- rxhdlr(rs_rxbuf,len-1);
-}
-
-void rsbus_init(rshdlr hdlr) // If need to change this part consult user guide pg908
-{
- P1SEL |= BIT1 + BIT2 ; // P1.1 = RXD, P1.2=TXD
- P1SEL2 |= BIT1 + BIT2 ; // P1.1 = RXD, P1.2=TXD
- UCA0CTL1 |= UCSSEL_2; // UartCLK: SMCLK=4MHz
- UCA0BR0 = 208; // BaudRate: 19200
- UCA0BR1 = 0; // BaudRate: 19200
- UCA0MCTL = UCBRS0 + UCBRS1; // Modulation UCBRSx = 3
- UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
- IE2 |= UCA0RXIE; // Enable USCI_A0 RX interrupt
- /******************* CTL for output buffer ***********************/
- RSDIR |= RSPIN;
- RSOUT &= ~(RSPIN); //HIGH for ENABLE -> Low as DEFAULT
- /******************* SYSCTL INIT *************************/
- rxhdlr=hdlr;
- sysctl_reghdlr(RSSYSBIT,&rsbus_syscall);
-}
+/*
+ * rsbus.c
+ *
+ * Created on: 2014-4-26
+ * Author: Tuowen
+ */
+#include "rsbus.h"
+#include "sysctl.h"
+
+#define SYSRET (0xF0)
+#define INSREP (0x0F)
+
+// Maximum size of receive buffer
+#define RSMAX (20)
+
+#define CODE_LEN (6)
+
+unsigned char rs_rxbuf[RSMAX];
+unsigned char len;
+unsigned char pch;
+rshdlr rxhdlr;
+enum rs_stat{REST,ST,ADDR,READ,DISCARD,ED,DED};
+enum rs_stat rs_st=REST;
+
+unsigned char rs_tx[CODE_LEN+RS_MAX]={STBIT1,0,RSADDR,MACTYPE};
+volatile unsigned char tx_len;
+volatile unsigned char tx_pos=255;
+
+volatile unsigned char mac_stat[4]={0,0,0,0};
+
+// UART transmit routine
+#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);
+ tx_pos = 255;
+ }
+ else
+ UCA0TXBUF = rs_tx[tx_pos++]; // TX next character
+}
+
+// Inline send for ISR
+#pragma FUNC_ALWAYS_INLINE(rsbus_w_irq)
+static __inline void rsbus_w_irq(unsigned char* buf,unsigned int len)
+{
+ unsigned int i;
+ if (tx_pos < tx_len) // This shouldn't happen
+ return; // Race condition
+ RSOUT |= RSPIN;
+ tx_len=len+7;
+ unsigned int parity=MACTYPE^RSADDR;
+ rs_tx[1]=0; // Useless addr spec
+ for (i=0;i<len;++i)
+ parity^=(rs_tx[4+i]=buf[i]);
+ rs_tx[4+len]=parity;
+ rs_tx[5+len]=EDBIT0;
+ rs_tx[6+len]=EDBIT1;
+ tx_pos=0;
+ UCA0TXBUF=(STBIT0 & 0xff);
+ UC0IE |= UCA0TXIE;
+}
+
+#pragma vector=USCIAB0RX_VECTOR
+__interrupt void rsbus_rx(void)
+{
+ //IFG2&=(~UCA0RXIFG);
+ unsigned char 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)
+ rsbus_w_irq((unsigned char*)mac_stat,4); // RETURN CURRENT STATUS
+ else
+ SYSCALL_IRQ(RSSYSBIT); // SYSCTL call happened here!!!
+ }
+ else // Parity check failed
+ {
+ dat = SYSRET ^ INSREP; // RETURN REP
+ rsbus_w_irq(&dat,1);
+ }
+ }
+ else
+ {
+ rs_rxbuf[len++]=dat;
+ pch^=dat;
+ rs_st=READ;
+ if (len>=RSMAX)
+ rs_st=REST;
+ }
+ break;
+ }
+}
+
+void rsbus_w(int addr,unsigned char* buf,unsigned int len)
+{
+ while (tx_pos < tx_len) // This shouldn't happen
+ __delay_cycles(100); // Race condition -> wait
+ unsigned int i;
+ if (len>RS_MAX)
+ return;
+ RSOUT |= RSPIN;
+ tx_len=len+7;
+ unsigned int parity=addr^MACTYPE^RSADDR;
+ rs_tx[1]=addr; // Useless addr spec
+ for (i=0;i<len;++i)
+ parity^=(rs_tx[4+i]=buf[i]);
+ rs_tx[4+len]=parity;
+ rs_tx[5+len]=EDBIT0;
+ rs_tx[6+len]=EDBIT1;
+ tx_pos=0;
+ UCA0TXBUF=(STBIT0 & 0xff);
+ UC0IE |= UCA0TXIE;
+}
+
+void rsbus_syscall()
+{
+ rxhdlr(rs_rxbuf,len-1);
+}
+
+void rsbus_init(rshdlr hdlr) // If need to change this part consult user guide pg908
+{
+ P1SEL |= BIT1 + BIT2 ; // P1.1 = RXD, P1.2=TXD
+ P1SEL2 |= BIT1 + BIT2 ; // P1.1 = RXD, P1.2=TXD
+ UCA0CTL1 |= UCSSEL_2; // UartCLK: SMCLK=4MHz
+ UCA0BR0 = 0xA0; // BaudRate: 19200
+ UCA0BR1 = 1; // BaudRate: 19200
+ UCA0MCTL = UCBRS1+UCBRS2;// + UCBRS1; // Modulation UCBRSx = 3
+ UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
+ IE2 |= UCA0RXIE; // Enable USCI_A0 RX interrupt
+ /******************* CTL for output buffer ***********************/
+ RSDIR |= RSPIN;
+ RSOUT &= ~(RSPIN); //HIGH for ENABLE -> Low as DEFAULT
+ /******************* SYSCTL INIT *************************/
+ rxhdlr=hdlr;
+ sysctl_reghdlr(RSSYSBIT,&rsbus_syscall);
+}