summaryrefslogtreecommitdiff
path: root/rs422lib/main.c
blob: 34cb03e0c66d6fbb1f3ddf25dcc6ab1a238f871b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132

#include"precomp.h"
#include"rsbus.h"
#include"sysctl.h"

int cnt=0;
int cnt2=0;

void port_init(void)
{
    P1DIR |= BIT0+BIT6;      // P1.0 P1.6 output
    P1OUT = 0;
}

void received(unsigned char* str,unsigned int 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
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_A0 (void)
{
	++cnt;
	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: 40ms
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

	if (CALBC1_8MHZ ==0xFF || CALDCO_8MHZ == 0xFF)
		while(1)_BIS_SR(CPUOFF);            	// If calibration constants erased, trap CPU!!

	BCSCTL1 = CALBC1_16MHZ; 		    // Set range
	DCOCTL = CALDCO_16MHZ;  		    // Set DCO step + modulation£¬DCO=8MHz
	BCSCTL3 |= LFXT1S_2;                      // LFXT1 = VLO
	IFG1 &= ~OFIFG;                           // Clear OSCFault flag
	BCSCTL2 |= DIVS_2;      //  SMCLK = DCO/4 = 4MHz

	sysctl_init();
	port_init();
	TimerA0_Init();
	rsbus_init(&received);

	_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();
}