summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rs422lib/main.c67
-rw-r--r--rs422lib/precomp.h75
-rw-r--r--rs422lib/rsbus.c364
-rw-r--r--rs422lib/rsbus.h130
-rw-r--r--rs422lib/sysctl.c8
-rw-r--r--rs422lib/sysctl.h118
6 files changed, 418 insertions, 344 deletions
diff --git a/rs422lib/main.c b/rs422lib/main.c
index 2a2517f..34cb03e 100644
--- a/rs422lib/main.c
+++ b/rs422lib/main.c
@@ -4,6 +4,7 @@
#include"sysctl.h"
int cnt=0;
+int cnt2=0;
void port_init(void)
{
@@ -13,7 +14,52 @@ void port_init(void)
void received(unsigned char* str,unsigned int len)
{
- rsbus_w(0,str,len);
+ unsigned char ch;
+ switch (str[0])
+ {
+ case 1:// start
+ if (!MSTATE)
+ {
+ SWITCH_STATE(ST_RUN);
+ cnt2=0;
+ STATE(0)=0;
+ SYSCALL(TEST);
+ }
+ RETSTATE;
+ break;
+ case 2:// Get Res
+ if (MSTATE&ST_RUN)
+ {
+ ch=(unsigned char)(cnt2-STATE(0));
+ rsbus_w(0,&ch,1);
+ }
+ else
+ if (MSTATE&ST_RES)
+ {
+ SWITCH_STATE(ST_REST);
+ ch=(unsigned char)(cnt2);
+ rsbus_w(0,&ch,1);
+ }
+ else
+ RETSTATE;
+ break;
+ case 3:// Stop
+ if (MSTATE&ST_RUN)
+ {
+ SWITCH_STATE(ST_REST);
+ SYSSTOP(TEST);
+ }
+ RETSTATE;
+ break;
+ case 4:// Block
+ if (!MSTATE)
+ {
+ cnt2=0;
+ SWITCH_STATE(ST_BUSY);
+ }
+ RETSTATE;
+ }
+ //rsbus_w(0,str,len);
}
// Timer A0 interrupt service routine
@@ -24,13 +70,19 @@ __interrupt void Timer_A0 (void)
if (cnt==25)
{
STATE(0)=(STATE(0)+1)&0xFF;
+ if ((MSTATE&ST_BUSY) && !(MSTATE&ST_RES))
+ {
+ ++cnt2;
+ if (STATE(0)>200)
+ SWITCH_STATE(ST_BUSY|ST_RES);
+ }
cnt=0;
P1OUT^=BIT6;
}
}
//TIMER A0 initialize -
-// desired value: 5ms
+// desired value: 40ms
void TimerA0_Init(void)
{
// Configure TimerA0
@@ -60,9 +112,20 @@ void init_devices(void)
_BIS_SR(GIE);
}
+// Clock tick using cycle estimation
+void basic_running_ex()
+{
+ int i;
+ for (i=950;i>0;--i)
+ delay_ms(1);
+ ++cnt2;
+ SYSCALL(TEST);
+}
+
void main(void)
{
init_devices();
+ sysctl_reghdlr(TEST,basic_running_ex);
while(1)
sysroutine();
}
diff --git a/rs422lib/precomp.h b/rs422lib/precomp.h
index d2d2380..6e54606 100644
--- a/rs422lib/precomp.h
+++ b/rs422lib/precomp.h
@@ -1,37 +1,38 @@
-/*
- * precomp.h
- *
- * Created on: 2014-4-26
- * Author: Tuowen
- */
-
-#ifndef PRECOMP_H_
-#define PRECOMP_H_
-
-#include<msp430g2553.h>
-
-// ====== RSBUS configuration ======
-
-// Data Enable pin configuration
-// P1.0 -> red led
-#define RSDIR (P1DIR)
-#define RSOUT (P1OUT)
-#define RSPIN (BIT0)
-
-// This is the highest level
-#define RSSYSBIT (SYS_BIT0)
-
-// Specify the physical address on the rsbus
-#define RSADDR (1)
-
-// Machine Type
-// TYPE 0 is a dummy used for debug
-// Change it in real implementation
-#define MACTYPE (0x00)
-
-// ====== End RSBUS configuration ======
-
-//define delay func
-#define delay_ms(ms) __delay_cycles(16000*(ms))
-
-#endif /* PRECOMP_H_ */
+/*
+ * precomp.h
+ *
+ * Created on: 2014-4-26
+ * Author: Tuowen
+ */
+
+#ifndef PRECOMP_H_
+#define PRECOMP_H_
+
+#include<msp430g2553.h>
+
+// ====== RSBUS configuration ======
+
+// Data Enable pin configuration
+// P1.0 -> red led
+#define RSDIR (P1DIR)
+#define RSOUT (P1OUT)
+#define RSPIN (BIT0)
+
+// This is the highest level
+#define RSSYSBIT (SYS_BIT0)
+#define TEST (SYS_BIT1)
+
+// Specify the physical address on the rsbus
+#define RSADDR (1)
+
+// Machine Type
+// TYPE 0 is a dummy used for debug
+// Change it in real implementation
+#define MACTYPE (0x00)
+
+// ====== End RSBUS configuration ======
+
+//define delay func
+#define delay_ms(ms) __delay_cycles(16000*(ms))
+
+#endif /* PRECOMP_H_ */
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);
+}
diff --git a/rs422lib/rsbus.h b/rs422lib/rsbus.h
index 2e29b9b..1297d72 100644
--- a/rs422lib/rsbus.h
+++ b/rs422lib/rsbus.h
@@ -1,63 +1,67 @@
-/*
- * rsbus.h
- *
- * Created on: 2014-4-26
- * Author: Tuowen
- */
-
-// DE RSOUT.RSPIN HIGH ENABLE
-// RE LOW ENABLE -> ALWAYS ENABLE
-// RECEIVE QUERY -> Conditional FNC call
-// Process -> Output (Done in main program)
-// SMCLK set to 4MHZ
-
-
-#ifndef RSBUS_H_
-#define RSBUS_H_
-
-#include<msp430g2553.h>
-#include"precomp.h"
-
-// MAXIMUM length to be send
-#define RS_MAX (14)
-
-#define ST_BUSY (0x04)
-#define ST_RUN (0x02)
-#define ST_RES (0x01)
-#define ST_REST (0x00)
-
-// Switch the machine to a new state specified above
-// This will shown on the network -> must call
-#define SWITCH_STATE(STATE) (mac_stat[0]=STATE)
-
-// Changing the state value (unsigned char) ->
-// Available indices 0,1,2
-#define STATE(X) (mac_stat[X+1])
-
-// Start and Stop bits definition
-// Every message sent that does not agree with it will be ignored
-// Please avoid this pattern in STATE(X)
-#define STBIT0 (0x5B)
-#define STBIT1 (0xAD)
-#define EDBIT0 (0xA4)
-#define EDBIT1 (0x52)
-
-// Receieve handler ->
-// Received message and it's length
-typedef void (*rshdlr)(unsigned char* msg,unsigned int len);
-
-// RSBUS init function
-// Setting up UART, DE pin, receieve handler
-void rsbus_init(rshdlr);
-
-// Send something to the rs422 bus
-// Length must not exceeds RS_MAX
-void rsbus_w(int,unsigned char*,unsigned int);
-
-// Machine status -> change it to change the auto respond status
-// 0 is reserved for machine state specification
-// 1-3 used for mac_type specific state
-// recommend using SWITCH_STATE & STATE
-extern volatile unsigned char mac_stat[4];
-
-#endif /* RSBUS_H_ */
+/*
+ * rsbus.h
+ *
+ * Created on: 2014-4-26
+ * Author: Tuowen
+ */
+
+// DE RSOUT.RSPIN HIGH ENABLE
+// RE LOW ENABLE -> ALWAYS ENABLE
+// RECEIVE QUERY -> Conditional FNC call
+// Process -> Output (Done in main program)
+// SMCLK set to 4MHZ
+
+
+#ifndef RSBUS_H_
+#define RSBUS_H_
+
+#include<msp430g2553.h>
+#include"precomp.h"
+
+// MAXIMUM length to be send
+#define RS_MAX (14)
+
+#define ST_BUSY (0x04)
+#define ST_RUN (0x02)
+#define ST_RES (0x01)
+#define ST_REST (0x00)
+
+// Switch the machine to a new state specified above
+// This will shown on the network -> must call
+#define SWITCH_STATE(STATE) (mac_stat[0]=STATE)
+#define MSTATE (mac_stat[0])
+
+// Changing the state value (unsigned char) ->
+// Available indices 0,1,2
+#define STATE(X) (mac_stat[X+1])
+
+// Return current mac state
+#define RETSTATE (rsbus_w(0,(unsigned char*)mac_stat,4))
+
+// Start and Stop bits definition
+// Every message sent that does not agree with it will be ignored
+// Please avoid this pattern in STATE(X)
+#define STBIT0 (0x5B)
+#define STBIT1 (0xAD)
+#define EDBIT0 (0xA4)
+#define EDBIT1 (0x52)
+
+// Receieve handler ->
+// Received message and it's length
+typedef void (*rshdlr)(unsigned char* msg,unsigned int len);
+
+// RSBUS init function
+// Setting up UART, DE pin, receieve handler
+void rsbus_init(rshdlr);
+
+// Send something to the rs422 bus
+// Length must not exceeds RS_MAX
+void rsbus_w(int,unsigned char*,unsigned int);
+
+// Machine status -> change it to change the auto respond status
+// 0 is reserved for machine state specification
+// 1-3 used for mac_type specific state
+// recommend using SWITCH_STATE & STATE
+extern volatile unsigned char mac_stat[4];
+
+#endif /* RSBUS_H_ */
diff --git a/rs422lib/sysctl.c b/rs422lib/sysctl.c
index cafcb62..ea05587 100644
--- a/rs422lib/sysctl.c
+++ b/rs422lib/sysctl.c
@@ -19,8 +19,11 @@ void sysctl_void()
}
void sysroutine()
+// << Drawback: interrupt may happen between else and CPUOFF
+// Critical section -> unlikely to have a race condition
{
- if (syscall>0)
+ if (!syscall)
+ _BIS_SR(CPUOFF);
switch ((syscall & (-syscall))) // This is used to get the lowest bit
{
case SYS_BIT7:
@@ -56,8 +59,7 @@ void sysroutine()
sysarr[0]();
break;
}
- else
- _BIS_SR(CPUOFF);
+
}
inline int sys_b2i(int bit)
diff --git a/rs422lib/sysctl.h b/rs422lib/sysctl.h
index b8301fa..83f82d9 100644
--- a/rs422lib/sysctl.h
+++ b/rs422lib/sysctl.h
@@ -1,57 +1,61 @@
-/*
- * sysctl.h
- *
- * Created on: 2014-4-26
- * Author: Tuowen
- */
-
-// Support 8 different syscalls
-// Possible improvement
-// CPUOFF all the time, wakeup after syscall invoked.
-
-#ifndef SYSCTL_H_
-#define SYSCTL_H_
-
-// Sysctl priority bit
-// Lowest first
-#define SYS_BIT7 (0x80)
-#define SYS_BIT6 (0x40)
-#define SYS_BIT5 (0x20)
-#define SYS_BIT4 (0x10)
-#define SYS_BIT3 (0x08)
-#define SYS_BIT2 (0x04)
-#define SYS_BIT1 (0x02)
-#define SYS_BIT0 (0x01)
-
-// SYSCALL invocation routine
-// Used this in IRQ, also wakes up the cpu
-#define SYSCALL_IRQ(X) (syscall|=X,_BIC_SR_IRQ(CPUOFF))
-// Use this in anywhere other than IRQ
-// Continuous invocation ?
-#define SYSCALL(X) (syscall|=X)
-
-// Call handler type
-// Does't have any input
-// Preserve the state in other global variables
-// Usage example -> rsbus_syscall()
-typedef void (*syshdlr)();
-
-// Register call handler
-// Always replace old value
-void sysctl_reghdlr(unsigned int bit,syshdlr rot);
-
-// Remove old call handler
-// Replace with something useless
-void sysctl_rmhdlr(unsigned int bit);
-
-// Insert it into mainloop
-// enabling automatic procedure invocation
-void sysroutine();
-
-// Setting up the proc base
-// Call before usage
-void sysctl_init();
-
-extern volatile unsigned char syscall;
-
-#endif /* SYSCTL_H_ */
+/*
+ * sysctl.h
+ *
+ * Created on: 2014-4-26
+ * Author: Tuowen
+ */
+
+// Support 8 different syscalls
+// Possible improvement
+// CPUOFF all the time, wakeup after syscall invoked.
+
+#ifndef SYSCTL_H_
+#define SYSCTL_H_
+
+// Sysctl priority bit
+// Lowest first
+#define SYS_BIT7 (0x80)
+#define SYS_BIT6 (0x40)
+#define SYS_BIT5 (0x20)
+#define SYS_BIT4 (0x10)
+#define SYS_BIT3 (0x08)
+#define SYS_BIT2 (0x04)
+#define SYS_BIT1 (0x02)
+#define SYS_BIT0 (0x01)
+
+// SYSCALL invocation routine
+// Used this in IRQ, also wakes up the cpu
+#define SYSCALL_IRQ(X) (syscall|=X,_BIC_SR_IRQ(CPUOFF))
+// Use this in anywhere other than IRQ
+// Continuous invocation ?
+#define SYSCALL(X) (syscall|=X)
+
+// Only one stop function
+// For IRQ & Main
+#define SYSSTOP(X) (syscall&=~X)
+
+// Call handler type
+// Does't have any input
+// Preserve the state in other global variables
+// Usage example -> rsbus_syscall()
+typedef void (*syshdlr)();
+
+// Register call handler
+// Always replace old value
+void sysctl_reghdlr(unsigned int bit,syshdlr rot);
+
+// Remove old call handler
+// Replace with something useless
+void sysctl_rmhdlr(unsigned int bit);
+
+// Insert it into mainloop
+// enabling automatic procedure invocation
+void sysroutine();
+
+// Setting up the proc base
+// Call before usage
+void sysctl_init();
+
+extern volatile unsigned char syscall;
+
+#endif /* SYSCTL_H_ */