Added 20MHz variant
[DueTest.git] / DueTest.cpp
1 #include "arduino.h"
2
3 static const int CONTROLINPUT = A0;
4 static const int TEMPINPUT[] = {A1, A2};
5 static const int MOTOROUTPUT = 3;
6 //static const int MOTOROFF = 255;
7 static const int MOTOROFF = 0;
8
9 static const int TEMP45C  = (45  - 21) * 76 / 10;
10 static const int TEMP80C  = (80  - 21) * 76 / 10;
11 static const int TEMP70C  = (70  - 21) * 76 / 10;
12 static const int TEMP112C = (112 - 21) * 76 / 10;
13
14 static const int TEMPHIGH = TEMP80C;
15 static const int TEMPSAFE = TEMP70C;
16
17 static const int HITEMP = 999;
18 static const int PERIOD1 = 100;
19 static const int PERIOD2 = 1000;
20
21 static const int TEMPCOUNT = sizeof (TEMPINPUT) / sizeof (int);
22
23 static int FixedMarkSpace = 0;
24 static int ControlInput = 0;
25 static int TempInput[TEMPCOUNT];
26 static int MotorOutput = 0;
27 static int TempHigh = 0;
28 static int period = 0;
29
30 // For page references see p423 (Register Summary)
31
32 // For Timer 2
33 //  Table 17-9 p162 : Prescaler
34 static const unsigned char CS2_STOP    = 0b00000000;
35 static const unsigned char CS2_NOSCALE = 0b00000001;
36 static const unsigned char CS2_0008    = 0b00000010;
37 static const unsigned char CS2_0032    = 0b00000011;
38 static const unsigned char CS2_0064    = 0b00000100;
39 static const unsigned char CS2_0128    = 0b00000101;
40 static const unsigned char CS2_0256    = 0b00000110;
41 static const unsigned char CS2_1024    = 0b00000111;
42
43 // Phase correct PWM (16MHz):
44
45 // 16 000 000 Hz / 512 = 31 250 Hz ~ 31kHz
46
47 // 31 250 /    8 = 3 906.25     Hz ~  4kHz
48 // 31 250 /   32 =   976.562 5  Hz ~  1kHz
49 // 31 250 /   64 =   488.281 25 Hz ~ 500Hz
50 // 31 250 /  128 =   244.140 625Hz ~ 250Hz
51 // 31 250 /  256 =   122.070 313Hz ~ 120Hz
52 // 31 250 / 1024 =    30.517 578Hz ~  30Hz
53
54 // Fast PWM (16MHz):
55
56 // 16 000 000 Hz / 256 = 62 500 Hz ~ 63kHz
57
58 // 62 500 /    8 = 7 812.5  Hz ~  8kHz
59 // 62 500 /   32 = 1 953.125Hz ~  2kHz
60 // 62 500 /   64 =   976.563Hz ~  1kHz
61 // 62 500 /  128 =   488.281Hz ~ 500Hz
62 // 62 500 /  256 =   244.141Hz ~ 240Hz
63 // 62 500 / 1024 =    61.035Hz ~  60Hz
64
65 // Phase correct PWM (20MHz):
66
67 // 20 000 000 Hz / 512 = 39 062.5 Hz ~ 40kHz
68
69 // 39 062.5 /    8 = 4 882.812Hz ~  5kHz
70 // 39 062.5 /   32 = 1 220.703Hz ~  1kHz
71 // 39 062.5 /   64 =   610.352Hz ~ 600Hz
72 // 39 062.5 /  128 =   305.176Hz ~ 300Hz
73 // 39 062.5 /  256 =   152.588Hz ~ 150Hz
74 // 39 062.5 / 1024 =    38.147Hz ~  40Hz
75
76 // Fast PWM (20MHz):
77
78 // 20 000 000 Hz / 256 = 78 125 Hz ~ 80kHz
79
80 // 78 125 /    8 = 9 765.625Hz ~  10kHz
81 // 78 125 /   32 = 2 441.406Hz ~ 2.5kHz
82 // 78 125 /   64 = 1 220.703Hz ~   1kHz
83 // 78 125 /  128 =   610.352Hz ~  600Hz
84 // 78 125 /  256 =   305.177Hz ~  300Hz
85 // 78 125 / 1024 =   152.588Hz ~   60Hz
86
87 void UARTReceive(char Character)
88 {
89     Serial.print (Character);
90
91     static unsigned char timerprescale = 0;
92
93     if (Character == '0')
94         FixedMarkSpace = 0;
95     
96     if (Character >= '0' && Character <= '9')
97         FixedMarkSpace = Character - '0';
98
99     if (Character == 's')
100         timerprescale = CS2_1024;
101
102     if (Character == 'm')
103         timerprescale = CS2_0008;
104
105     if (Character == 'f')
106         timerprescale = CS2_NOSCALE;
107     
108     if (Character == 'h')
109     {
110         timerprescale = TCCR2B & 0b00000111;
111         TCCR2A |= _BV(WGM21);
112     }
113
114     if (Character == 'l')
115     {
116         timerprescale = TCCR2B & 0b00000111;
117         TCCR2A &= ~_BV(WGM21);
118     }
119
120     if (timerprescale)
121     {
122 // Set prescaler and start PWM
123         TCCR2B &= ~0b00000111;
124         TCCR2B |= timerprescale;
125     }
126
127     if (Character == 'd')
128     {
129         switch (period)
130         {
131             case 0: period = PERIOD1; break;
132             case PERIOD1: period = PERIOD2; break;
133             case PERIOD2: period = 0; break;
134             default: period = 0; break;
135         }
136     }
137 }
138
139 void setup ()
140 {
141     Serial.begin (115200);
142     Serial.println ("Grahams Motor Test, " __DATE__ " (" __TIME__ ")");
143
144 // Set prescaler and start PWM
145     TCCR2B &= ~0b00000111;
146     TCCR2B |= CS2_NOSCALE;
147 }
148
149 static inline int TempInC (int Input)
150 {
151 // For 1k lowside: 45C < Temp ~ +-1C < 112C
152     if (Input < TEMP45C)
153         return 0;
154     else if (Input > TEMP112C)
155         return HITEMP;
156     else
157         return (Input * 10 / 76) + 21;
158 }
159
160 void loop ()
161 {
162     if (FixedMarkSpace)
163         ControlInput = (FixedMarkSpace << 10) / 10;
164     else
165         ControlInput = analogRead (CONTROLINPUT);
166
167     int TempLow = 1;
168
169     for (unsigned char count = 0; count < TEMPCOUNT; count++)
170     {
171         TempInput[count] = analogRead (TEMPINPUT[count]);
172
173         if (TempInput[count] >= TEMPSAFE)
174             TempLow = 0;
175
176         if (TempInput[count] > TEMPHIGH)
177             TempHigh = 1;
178     }
179
180     if (TempLow)
181         TempHigh = 0;
182
183     MotorOutput = ControlInput >> 2;
184
185     if (TempHigh)
186         MotorOutput = MOTOROFF;
187     else
188         MotorOutput = ControlInput >> 2;
189
190     analogWrite (MOTOROUTPUT, MotorOutput);
191
192     Serial.print ("ControlInput = ");
193     Serial.print (ControlInput);
194
195     Serial.print ("\tTempInput ");
196
197     for (unsigned char count = 0; count < TEMPCOUNT; count++)
198     {
199         Serial.print (count);
200         Serial.print (" = ");
201         Serial.print (TempInput[count]);
202         Serial.print ("(");
203         Serial.print (TempInC(TempInput[count]));
204         Serial.print ("C)\t");
205     }
206
207     Serial.print ("MotorOutput = ");
208     Serial.println (MotorOutput);
209
210     if (period == PERIOD1)
211         delay (PERIOD1);
212     else if (period == PERIOD2)
213         delay (PERIOD2);
214 }