diff options
-rw-r--r-- | rs422lib/main.c | 26 | ||||
-rw-r--r-- | rs422lib/rsbus.c | 59 | ||||
-rw-r--r-- | rs422lib/rsbus.h | 11 |
3 files changed, 76 insertions, 20 deletions
diff --git a/rs422lib/main.c b/rs422lib/main.c index 8f6ec49..7f7ea11 100644 --- a/rs422lib/main.c +++ b/rs422lib/main.c @@ -3,6 +3,8 @@ #include"rsbus.h" #include"sysctl.h" +int cnt=0; + void port_init(void) { P1DIR |= BIT0+BIT6; // P1.0 P1.6 output @@ -14,6 +16,29 @@ void received(unsigned char* str,int len) rsbus_w(0,str,len); } +// Timer A0 interrupt service routine +#pragma vector=TIMER0_A0_VECTOR +__interrupt void Timer_A0 (void) +{ + ++cnt; + if (cnt==25) + { + STATE(0)=(STATE(0)+1)&0xFF; + cnt=0; + P1OUT^=BIT6; + } +} + +//TIMER A0 initialize - +// desired value: 5ms +void TimerA0_Init(void) +{ + // Configure TimerA0 + TA0CTL = TASSEL_2 + MC_1 +ID_3 ; // Source: SMCLK=4MHz, UP mode, DIV by 8 -> 0.5M + TA0CCR0 = 20000; // 0.5MHz / 20000 -> 25Hz -> 40ms + TA0CCTL0 = CCIE; // CCR0 interrupt enabled +} + void init_devices(void) { WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer @@ -29,6 +54,7 @@ void init_devices(void) sysctl_init(); port_init(); + TimerA0_Init(); rsbus_init(&received); _BIS_SR(GIE); diff --git a/rs422lib/rsbus.c b/rs422lib/rsbus.c index 2e63594..4c0fcb2 100644 --- a/rs422lib/rsbus.c +++ b/rs422lib/rsbus.c @@ -13,14 +13,15 @@ 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[15]={STBIT1,0,RSADDR,MACTYPE};
-unsigned char tx_len;
-unsigned char tx_pos;
+unsigned char rs_tx[20]={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};
#pragma vector=USCIAB0TX_VECTOR
__interrupt void USCI0TX_ISR(void)
@@ -29,16 +30,39 @@ __interrupt void USCI0TX_ISR(void) {
UC0IE &= ~UCA0TXIE; // Disable USCI_A0 TX interrupt
RSOUT &= ~(RSPIN);
+ tx_pos = 255;
}
else
UCA0TXBUF = rs_tx[tx_pos++]; // TX next character
}
+#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
+ rs_tx[2]=RSADDR;
+ rs_tx[3]=MACTYPE;
+ 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);
- int dat;
+ unsigned char dat;
dat=UCA0RXBUF;
/************ Simple State Machine *************/
switch (rs_st)
@@ -86,17 +110,14 @@ __interrupt void rsbus_rx(void) if (pch==0) // Parity check passed
{
if (len<2)
- {
- ret=(SYSRET ^ MACTYPE);
- SYSCALL_IRQ(RSSYSRET); // TODO RETURN CURRENT STATUS
- }
+ rsbus_w_irq((unsigned char*)mac_stat,4); // RETURN CURRENT STATUS
else
SYSCALL_IRQ(RSSYSBIT); // SYSCTL call happened here!!!
}
- else
+ else // Parity check failed
{
- ret=(SYSRET ^ INSREP);
- SYSCALL_IRQ(RSSYSRET); // RETURN machine type
+ dat = SYSRET ^ INSREP; // RETURN REP
+ rsbus_w_irq(&dat,1);
}
}
else
@@ -113,13 +134,17 @@ __interrupt void rsbus_rx(void) 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>4)
+ if (len>14)
return;
RSOUT |= RSPIN;
tx_len=len+7;
unsigned int parity=addr^MACTYPE^RSADDR;
- rs_tx[1]=addr;
+ rs_tx[1]=addr; // Useless addr spec
+ rs_tx[2]=RSADDR;
+ rs_tx[3]=MACTYPE;
for (i=0;i<len;++i)
parity^=(rs_tx[4+i]=buf[i]);
rs_tx[4+len]=parity;
@@ -135,11 +160,6 @@ void rsbus_syscall() rxhdlr(rs_rxbuf,len-1);
}
-void rsbus_ret()
-{
- rsbus_w(0,(unsigned char*)&ret,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
@@ -156,5 +176,4 @@ void rsbus_init(rshdlr hdlr) // If need to change this part consult user guide p /******************* SYSCTL INIT *************************/
rxhdlr=hdlr;
sysctl_reghdlr(RSSYSBIT,&rsbus_syscall);
- sysctl_reghdlr(RSSYSRET,&rsbus_ret);
}
diff --git a/rs422lib/rsbus.h b/rs422lib/rsbus.h index 036195d..ea66148 100644 --- a/rs422lib/rsbus.h +++ b/rs422lib/rsbus.h @@ -18,6 +18,15 @@ #include<msp430g2553.h>
#include"precomp.h"
+#define ST_BUSY (0x04)
+#define ST_RUN (0x02)
+#define ST_RES (0x01)
+#define ST_REST (0x00)
+
+#define SWITCH_STATE(STATE) (mac_stat[0]=STATE)
+
+#define STATE(X) (mac_stat[X+1])
+
#define TYPE0 (0x00) //TYPE 0 is a dummy used for debug
#define TYPE1 (0x01)
@@ -38,4 +47,6 @@ void rsbus_init(rshdlr); void rsbus_w(int addr,unsigned char* buf,unsigned int len);
+extern volatile unsigned char mac_stat[4]; // Machine status -> change it to change the auto respond status
+
#endif /* RSBUS_H_ */
|