-
Notifications
You must be signed in to change notification settings - Fork 5
/
dcodemo.c
188 lines (157 loc) · 4.42 KB
/
dcodemo.c
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
/*
* Based on:
* http://sites.google.com/site/mspscifiles/tutorials/dcodemo_g2211.c?attredirects=0&d=1
*
* Description at:
* http://mspsci.blogspot.com.br/2010/07/tutorial-08-b-configuring-dco.html
*
* Demonstrates configuration of the DCO by showing changing LED flash frequency.
* The LED flash uses the same delay loop, but the speed at which the loop runs
* depends on the DCO frequency running MCLK.
*
* int dco(unsigned int rsel, unsigned int dco) - consumes 4 ints of memory but
* it is easy to understand.
*
* int dco2(unsigned int rsel, unsigned int dco) - consumes 2 ints of memory
* but is a little tricky.
*
* #define DCO3(rsel,dco) - consumes no memory but is tricky and may be
* dangerous
*
*/
#include <msp430x20x2.h>
#define REDLED BIT0
#define GREENLED BIT6
#define BUTTON BIT3
#define DCOCTL_MASK 0xe0 //0b11100000
#define BCSCTL1_MASK 0x0f //0b00001111
/* Consumes no memory but it is tricky and may be dangerous
* see dco() and dco2()
*/
#define DCO3(rsel,dco) {\
if ((rsel >= 0) && (rsel <= 15) && (dco >= 0) && (dco <= 7)){\
BCSCTL1 = ((BCSCTL1 & ~BCSCTL1_MASK) | (rsel));\
DCOCTL = ((DCOCTL & ~DCOCTL_MASK) | (dco << 5));\
} else \
blink(REDLED, 2);\
}
void blink(unsigned int led, unsigned int times);
int dco(unsigned int rsel, unsigned int dco);
int dco2(unsigned int rsel, unsigned int dco);
void delay(void);
/*
* if (dco(2, 6) < 0)
* blink(REDLED, 2); // Error!
*
* blink(GREENLED, 5);
* while ((P1IN&BUTTON) == BUTTON); // wait for button press
*
*/
int main(void) {
WDTCTL = WDTPW + WDTHOLD;
P1OUT = 0;
P1DIR = REDLED+GREENLED;
for (;;) {
if (dco(11, 3) < 0)
blink(REDLED, 2);
blink(GREENLED, 5);
while ((P1IN&BUTTON) == BUTTON);
if (dco2(11, 3) < 0)
blink(REDLED, 2);
blink(GREENLED, 5);
while ((P1IN&BUTTON) == BUTTON);
DCO3(11, 3);
blink(GREENLED, 5);
while ((P1IN&BUTTON) == BUTTON);
if (dco(20, 8) < 0)
blink(REDLED, 2);
while ((P1IN&BUTTON) == BUTTON);
if (dco2(20, 8) < 0)
blink(REDLED, 2);
while ((P1IN&BUTTON) == BUTTON);
DCO3(20, 8);
while ((P1IN&BUTTON) == BUTTON);
}
}
void blink(unsigned int led, unsigned int times)
{
for (; times > 0; times--){
P1OUT |= led;
delay();
P1OUT &= ~led;
delay();
}
}
/* From: http://www.ti.com/lit/ds/symlink/msp430g2231.pdf page 23
* This is chip specific. For the MSP430G2231 using 3V at 25C:
*
* dco(0,0) = [0.06 , 0.14] Mhz
* dco(0,3) = 0.12 Mhz
* dco(1,3) = 0.15 Mhz
* dco(2,3) = 0.21 Mhz
* dco(3,3) = 0.30 Mhz
* dco(3,3) = 0.30 Mhz
* dco(4,3) = 0.41 Mhz
* dco(5,3) = 0.58 Mhz
* dco(6,3) = 0.80 Mhz
* dco(7,3) = [0.8 , 1.5] Mhz
* dco(8,3) = 1.6 Mhz
* dco(9,3) = 2.3 Mhz
* dco(10,3) = 3.4 Mhz
* dco(11,3) = 4.25 Mhz
* dco(12,3) = [4.3 , 7.3] Mhz
* dco(13,3) = 7.8 Mhz
* dco(14,3) = [8.6 , 13.9] Mhz
* dco(15,3) = 15.25 Mhz
* dco(15,7) = 21.00 Mhz
*
*/
/* This is easier to understand but consumes 4 ints of memory */
int dco(unsigned int rsel, unsigned int dco)
{
unsigned int bcsctl1, dcoctl;
/* Check if parameters are in correct range */
if ((rsel < 0) || (rsel > 15) || (dco < 0) || (dco > 7))
return -1;
/* Shift dco so the 3 less significant bits
* become the 3 more signigicant bits */
dco = dco << 5;
/* read the registers */
bcsctl1 = BCSCTL1;
dcoctl = DCOCTL;
/* set zeros */
bcsctl1 &= (rsel & BCSCTL1_MASK);
dcoctl &= (dco & DCOCTL_MASK);
/* set ones */
bcsctl1 |= (rsel & BCSCTL1_MASK);
dcoctl |= (dco & DCOCTL_MASK);
/* save it back to the registers */
BCSCTL1 = bcsctl1;
DCOCTL = dcoctl;
return 0;
}
/* This is more tricky but consumes only 2 ints of memory */
int dco2(unsigned int rsel, unsigned int dco)
{
/* Check if parameters are in correct range */
if ((rsel < 0) || (rsel > 15) || (dco < 0) || (dco > 7))
return -1;
/* Shift dco so the 3 less significant bits
* become the 3 more signigicant bits */
dco = dco << 5;
/* We want to change only the bits described by BCSCTL1_MASK and
* DCOCTL_MASK. Using |= (BCSCTL1 & ~BCSCTL1_MASK) and
* |= (DCOCTL & ~DCOCTL_MASK) only reads the bits we will not change.
*/
rsel |= (BCSCTL1 & ~BCSCTL1_MASK);
dco |= (DCOCTL & ~DCOCTL_MASK);
/* save it back to the registers */
BCSCTL1 = rsel;
DCOCTL = dco;
return 0;
}
void delay(void)
{
volatile unsigned int n;
for (n = 0; n < 60000; n++);
}