summaryrefslogtreecommitdiffstats
path: root/linz/glasslathe
diff options
context:
space:
mode:
Diffstat (limited to 'linz/glasslathe')
-rw-r--r--linz/glasslathe/platformio.ini7
-rw-r--r--linz/glasslathe/src/main.cpp166
2 files changed, 90 insertions, 83 deletions
diff --git a/linz/glasslathe/platformio.ini b/linz/glasslathe/platformio.ini
index f2cb76e..ed9ba0a 100644
--- a/linz/glasslathe/platformio.ini
+++ b/linz/glasslathe/platformio.ini
@@ -8,8 +8,7 @@
8; Please visit documentation for the other options and examples 8; Please visit documentation for the other options and examples
9; https://docs.platformio.org/page/projectconf.html 9; https://docs.platformio.org/page/projectconf.html
10 10
11[env:nanoatmega328new] 11[env:mkrzero]
12platform = atmelavr 12platform = atmelsam
13board = nanoatmega328new
14framework = arduino 13framework = arduino
15lib_deps = paulstoffregen/TimerOne @ ^1.1 \ No newline at end of file 14board = mkrzero
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
14 while (GCLK->STATUS.bit.SYNCBUSY); // Wait for synchronization
8 15
9 // Set the timer to mode 14... 16 GCLK->GENCTRL.reg = GCLK_GENCTRL_IDC | // Set the duty cycle to 50/50 HIGH/LOW
10 // 17 GCLK_GENCTRL_GENEN | // Enable GCLK4
11 // Mode WGM13 WGM12 WGM11 WGM10 Timer/Counter Mode of Operation TOP Update of OCR1x at TOV1 Flag Set on 18 GCLK_GENCTRL_SRC_DFLL48M | // Set the 48MHz clock source
12 // CTC1 PWM11 PWM10 19 GCLK_GENCTRL_ID(4); // Select GCLK4
13 // ---- ----- ----- ----- ----- ------------------------------- ---- ----------------------- ----------- 20 while (GCLK->STATUS.bit.SYNCBUSY); // Wait for synchronization
14 // 14 1 1 1 0 Fast PWM ICR1 BOTTOM TOP
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
19 // ------ ------ -----------------------------------------------------------
20 // 1 0 Clear OC1A/OC1B on Compare Match (Set output to low level).
21 TCCR1A =
22 (1 << COM1A1) | (0 << COM1A0) | // COM1A1, COM1A0 = 1, 0
23 (0 << COM1B1) | (0 << COM1B0) |
24 (1 << WGM11) | (0 << WGM10); // WGM11, WGM10 = 1, 0
25 24
26 // Set TOP to... 25 // Connect the TCC timers to the port outputs - port pins are paired odd PMUO and even PMUXE
27 // 26 // F & E specify the timers: TCC0, TCC1 and TCC2
28 // fclk_I/O = 16000000 27 PORT->Group[g_APinDescription[5].ulPort].PMUX[g_APinDescription[5].ulPin >> 1].reg = PORT_PMUX_PMUXO_F;
29 // N = 1 28
30 // TOP = 799 29 // Feed GCLK4 to TCC0 and TCC1
31 // 30 GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN | // Enable GCLK4 to TCC0 and TCC1
32 // fOCnxPWM = fclk_I/O / (N * (1 + TOP)) 31 GCLK_CLKCTRL_GEN_GCLK4 | // Select GCLK4
33 // fOCnxPWM = 16000000 / (1 * (1 + 799)) 32 GCLK_CLKCTRL_ID_TCC0_TCC1; // Feed GCLK4 to TCC0 and TCC1
34 // fOCnxPWM = 16000000 / 800 33 while (GCLK->STATUS.bit.SYNCBUSY); // Wait for synchronization
35 // fOCnxPWM = 20000
36 ICR1 = 799;
37 34
38 // Ensure the first slope is complete 35 TCC0->WAVE.reg = TCC_WAVE_WAVEGEN_NPWM; // Single slope PWM operation
39 TCNT1 = 0; 36 while (TCC0->SYNCBUSY.bit.WAVE); // Wait for synchronization
37
38 TCC0->PER.reg = 4799; // Set the frequency of the PWM on TCC0 to 10kHz
39 while (TCC0->SYNCBUSY.bit.PER); // Wait for synchronization
40 40
41 // Ensure Channel B is irrelevant 41 TCC0->CC[2].reg = 2399; // TCC0 CC2 - 50% duty-cycle on D10
42 OCR1B = 0; 42 while (TCC0->SYNCBUSY.bit.CC2); // Wait for synchronization
43 TCC0->CC[3].reg = 2399; // TCC0 CC3 - 50% duty-cycle on D12
44 while (TCC0->SYNCBUSY.bit.CC3); // Wait for synchronization
45
46 // Divide the 48MHz signal by 1 giving 48MHz (20.83ns) TCC0 timer tick and enable the timer
47 TCC0->CTRLA.reg |= TCC_CTRLA_PRESCALER_DIV1 | // Divide GCLK4 by 1
48 TCC_CTRLA_ENABLE; // Enable the TCC0 output
49 while (TCC0->SYNCBUSY.bit.ENABLE); // Wait for synchronization
43 50
44 // Ensure Channel A starts at zero / off 51 //Stop TCC0 counter on MCU initialization (stepper initially stopped)
45 OCR1A = 0; 52 //TCC0->CTRLBSET.reg = TCC_CTRLBSET_CMD_STOP; // Force the TCC0 timer to STOP
53 //while (TCC0->SYNCBUSY.bit.CTRLB); // Wait for synchronization
54}
46 55
47 // We don't need no stinkin interrupts 56void StopTimer()
48 TIMSK1 = (0 << ICIE1) | (0 << OCIE1B) | (0 << OCIE1A) | (0 << TOIE1); 57{
58 //Stop TCC0 counter on MCU initialization (stepper initially stopped)
59 TCC0->CTRLBSET.reg = TCC_CTRLBSET_CMD_STOP; // Force the TCC0 timer to STOP
60 while (TCC0->SYNCBUSY.bit.CTRLB); // Wait for synchronization
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}
49 69
50 // Ensure the Channel A pin is configured for output 70uint32_t stepperFrequencyDivisor = 4799; //Sets the starting frequency equal to 1hz
51 DDRB |= (1 << DDB1);
52 71
53 // Start the timer... 72void SetFrequencyOutput(uint16_t frequency)
54 // 73{
55 // CS12 CS11 CS10 Description 74 stepperFrequencyDivisor = round(48000000 / frequency);
56 // ---- ---- ---- ------------------------ 75
57 // 0 0 1 clkI/O/1 (No prescaling) 76 TCC0->PERB.reg = stepperFrequencyDivisor - 1; // Set the starting frequency of the PWM on TCC0 to 1Hz
58 TCCR1B = 77 while (TCC0->SYNCBUSY.bit.PERB); // Wait for synchronization
59 (0 << ICNC1) | (0 << ICES1) | 78
60 (1 << WGM13) | (1 << WGM12) | // WGM13, WGM12 = 1, 1 79 TCC0->CCB[1].reg = (stepperFrequencyDivisor / 2) - 1; // TCC0 CC2 - 50% duty-cycle
61 (0 << CS12) | (0 << CS11) | (1 << CS10); 80 while (TCC0->SYNCBUSY.bit.CCB2); // Wait for synchronization
62} 81}
63 82
64void analogWriteD9(uint16_t value) 83void SetMotorOutput(uint16_t rpm)
65{ 84{
66 if ((value >= 0) && (value < 800)) 85 const float stepperHzToRPM = 1; //6.67hz runs the stepper at 1 RPM
67 { 86 SetFrequencyOutput(rpm * stepperHzToRPM);
68 OCR1A = value;
69 }
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