diff options
author | Joe Zhao <ztuowen@gmail.com> | 2014-05-23 15:36:51 +0800 |
---|---|---|
committer | Joe Zhao <ztuowen@gmail.com> | 2014-05-23 15:36:51 +0800 |
commit | 07d2ace8b4771e2ad48d4a9e6bf43a2022a25fac (patch) | |
tree | 8f76b7e3ce69ceb6d7822ec9aa8977a830d10c8d /rs422lib/rsbus.c | |
parent | d9c0c179fc4636b8927dd2c8b2cb29d573094731 (diff) | |
download | rsbus-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.c | 364 |
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); +} |