summaryrefslogtreecommitdiffstats
path: root/linz/glasslathe/src/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'linz/glasslathe/src/main.cpp')
-rw-r--r--linz/glasslathe/src/main.cpp184
1 files changed, 96 insertions, 88 deletions
diff --git a/linz/glasslathe/src/main.cpp b/linz/glasslathe/src/main.cpp
index 85b49dd..cd39208 100644
--- a/linz/glasslathe/src/main.cpp
+++ b/linz/glasslathe/src/main.cpp
@@ -1,104 +1,112 @@
1#include <Arduino.h> 1#include <Arduino.h>
2#include <TimerOne.h>
3 2
4void analogWriteSAH_Init(void) 3#define LED_PIN 4
4#define POT_PIN 2
5
6#define POT_JITTER_THRESHOLD 10
7
8int potValue = 0;
9
10void SetupTimer()
5{ 11{
6 // Stop the timer while we muck with it 12 GCLK->GENDIV.reg = GCLK_GENDIV_DIV(1) | // Divide the 48MHz clock source by divisor 1: 48MHz/1=48MHz
7 TCCR1B = (0 << ICNC1) | (0 << ICES1) | (0 << WGM13) | (0 << WGM12) | (0 << CS12) | (0 << CS11) | (0 << CS10); 13 GCLK_GENDIV_ID(4); // Select Generic Clock (GCLK) 4
8 14 while (GCLK->STATUS.bit.SYNCBUSY); // Wait for synchronization
9 // Set the timer to mode 14... 15
10 // 16 GCLK->GENCTRL.reg = GCLK_GENCTRL_IDC | // Set the duty cycle to 50/50 HIGH/LOW
11 // Mode WGM13 WGM12 WGM11 WGM10 Timer/Counter Mode of Operation TOP Update of OCR1x at TOV1 Flag Set on 17 GCLK_GENCTRL_GENEN | // Enable GCLK4
12 // CTC1 PWM11 PWM10 18 GCLK_GENCTRL_SRC_DFLL48M | // Set the 48MHz clock source
13 // ---- ----- ----- ----- ----- ------------------------------- ---- ----------------------- ----------- 19 GCLK_GENCTRL_ID(4); // Select GCLK4
14 // 14 1 1 1 0 Fast PWM ICR1 BOTTOM TOP 20 while (GCLK->STATUS.bit.SYNCBUSY); // Wait for synchronization
15 21
16 // Set output on Channel A to... 22 // Enable the port multiplexer for port D5
17 // 23 PORT->Group[g_APinDescription[5].ulPort].PINCFG[g_APinDescription[5].ulPin].bit.PMUXEN = 1;
18 // COM1A1 COM1A0 Description 24
19 // ------ ------ ----------------------------------------------------------- 25 // Connect the TCC timers to the port outputs - port pins are paired odd PMUO and even PMUXE
20 // 1 0 Clear OC1A/OC1B on Compare Match (Set output to low level). 26 // F & E specify the timers: TCC0, TCC1 and TCC2
21 TCCR1A = 27 PORT->Group[g_APinDescription[5].ulPort].PMUX[g_APinDescription[5].ulPin >> 1].reg = PORT_PMUX_PMUXO_F;
22 (1 << COM1A1) | (0 << COM1A0) | // COM1A1, COM1A0 = 1, 0 28
23 (0 << COM1B1) | (0 << COM1B0) | 29 // Feed GCLK4 to TCC0 and TCC1
24 (1 << WGM11) | (0 << WGM10); // WGM11, WGM10 = 1, 0 30 GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN | // Enable GCLK4 to TCC0 and TCC1
25 31 GCLK_CLKCTRL_GEN_GCLK4 | // Select GCLK4
26 // Set TOP to... 32 GCLK_CLKCTRL_ID_TCC0_TCC1; // Feed GCLK4 to TCC0 and TCC1
27 // 33 while (GCLK->STATUS.bit.SYNCBUSY); // Wait for synchronization
28 // fclk_I/O = 16000000 34
29 // N = 1 35 TCC0->WAVE.reg = TCC_WAVE_WAVEGEN_NPWM; // Single slope PWM operation
30 // TOP = 799 36 while (TCC0->SYNCBUSY.bit.WAVE); // Wait for synchronization
31 // 37
32 // fOCnxPWM = fclk_I/O / (N * (1 + TOP)) 38 TCC0->PER.reg = 4799; // Set the frequency of the PWM on TCC0 to 10kHz
33 // fOCnxPWM = 16000000 / (1 * (1 + 799)) 39 while (TCC0->SYNCBUSY.bit.PER); // Wait for synchronization
34 // fOCnxPWM = 16000000 / 800 40
35 // fOCnxPWM = 20000 41 TCC0->CC[2].reg = 2399; // TCC0 CC2 - 50% duty-cycle on D10
36 ICR1 = 799; 42 while (TCC0->SYNCBUSY.bit.CC2); // Wait for synchronization
37 43 TCC0->CC[3].reg = 2399; // TCC0 CC3 - 50% duty-cycle on D12
38 // Ensure the first slope is complete 44 while (TCC0->SYNCBUSY.bit.CC3); // Wait for synchronization
39 TCNT1 = 0; 45
40 46 // Divide the 48MHz signal by 1 giving 48MHz (20.83ns) TCC0 timer tick and enable the timer
41 // Ensure Channel B is irrelevant 47 TCC0->CTRLA.reg |= TCC_CTRLA_PRESCALER_DIV1 | // Divide GCLK4 by 1
42 OCR1B = 0; 48 TCC_CTRLA_ENABLE; // Enable the TCC0 output
43 49 while (TCC0->SYNCBUSY.bit.ENABLE); // Wait for synchronization
44 // Ensure Channel A starts at zero / off 50
45 OCR1A = 0; 51 //Stop TCC0 counter on MCU initialization (stepper initially stopped)
46 52 //TCC0->CTRLBSET.reg = TCC_CTRLBSET_CMD_STOP; // Force the TCC0 timer to STOP
47 // We don't need no stinkin interrupts 53 //while (TCC0->SYNCBUSY.bit.CTRLB); // Wait for synchronization
48 TIMSK1 = (0 << ICIE1) | (0 << OCIE1B) | (0 << OCIE1A) | (0 << TOIE1);
49
50 // Ensure the Channel A pin is configured for output
51 DDRB |= (1 << DDB1);
52
53 // Start the timer...
54 //
55 // CS12 CS11 CS10 Description
56 // ---- ---- ---- ------------------------
57 // 0 0 1 clkI/O/1 (No prescaling)
58 TCCR1B =
59 (0 << ICNC1) | (0 << ICES1) |
60 (1 << WGM13) | (1 << WGM12) | // WGM13, WGM12 = 1, 1
61 (0 << CS12) | (0 << CS11) | (1 << CS10);
62} 54}
63 55
64void analogWriteD9(uint16_t value) 56void StopTimer()
65{ 57{
66 if ((value >= 0) && (value < 800)) 58 //Stop TCC0 counter on MCU initialization (stepper initially stopped)
67 { 59 TCC0->CTRLBSET.reg = TCC_CTRLBSET_CMD_STOP; // Force the TCC0 timer to STOP
68 OCR1A = value; 60 while (TCC0->SYNCBUSY.bit.CTRLB); // Wait for synchronization
69 } 61}
62
63void RestartTimer()
64{
65 // put your main code here, to run repeatedly:
66 TCC0->CTRLBSET.reg = TCC_CTRLBSET_CMD_RETRIGGER; // Force the TCC0 timer to START
67 while (TCC0->SYNCBUSY.bit.CTRLB); // Wait for synchronization
68}
69
70uint32_t stepperFrequencyDivisor = 4799; //Sets the starting frequency equal to 1hz
71
72void SetFrequencyOutput(uint16_t frequency)
73{
74 stepperFrequencyDivisor = round(48000000 / frequency);
75
76 TCC0->PERB.reg = stepperFrequencyDivisor - 1; // Set the starting frequency of the PWM on TCC0 to 1Hz
77 while (TCC0->SYNCBUSY.bit.PERB); // Wait for synchronization
78
79 TCC0->CCB[1].reg = (stepperFrequencyDivisor / 2) - 1; // TCC0 CC2 - 50% duty-cycle
80 while (TCC0->SYNCBUSY.bit.CCB2); // Wait for synchronization
81}
82
83void SetMotorOutput(uint16_t rpm)
84{
85 const float stepperHzToRPM = 1; //6.67hz runs the stepper at 1 RPM
86 SetFrequencyOutput(rpm * stepperHzToRPM);
70} 87}
71 88
72void setup() 89void setup()
73{ 90{
74 //analogWriteSAH_Init(); 91 SetupTimer();
75 Timer1.initialize(50);
76 Timer1.pwm(9, 1024/2);
77 Serial.begin(9600);
78} 92}
79 93
80void loop() 94void loop()
81{ 95{
82 static int old_poti = 0; 96 /*int newPotValue = analogRead(POT_PIN);
83 int poti = analogRead(A7) / 10; 97 if (abs(newPotValue - potValue) > POT_JITTER_THRESHOLD)
84 if (poti != old_poti) { 98 {
85 // period_us = 1 / khz * 1000 99 potValue = newPotValue;
86 int period_us = (poti == 0) ? 0 : map(poti, 1, 102, 600, 50); 100 SetFrequencyOutput(map(potValue, 0, 1023, 0, 20000));
87 Timer1.initialize(period_us); 101 }*/
88 Timer1.pwm(9, 1024/2); 102 for(uint8_t i = 0; i <= 20; i++)
89 Serial.println(poti); 103 {
90 Serial.println(period_us); 104 SetFrequencyOutput(i * 1000);
91 old_poti = poti; 105 delay(10000);
92 } 106 }
93 //Timer1.setPeriod(); 107 for(uint8_t i = 20; i >= 0; i--)
94 //Timer1.setPeriod(50); 108 {
95 //Timer1.restart(); 109 SetFrequencyOutput(i * 1000);
96 110 delay(10000);
97#if 0
98 for (float frequency = 500; frequency < 3000; frequency = frequency + 1) {
99 float T = 1 / frequency * 1000000;
100 //Timer1.setPeriod(T);
101 delay(5);
102 } 111 }
103#endif 112}
104} \ No newline at end of file