diff options
Diffstat (limited to 'rs422lib/rsbus.c')
-rw-r--r-- | rs422lib/rsbus.c | 59 |
1 files changed, 39 insertions, 20 deletions
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);
}
|