summaryrefslogtreecommitdiffstats
path: root/linz/glasslathe/src/main.cpp
blob: cd392085429060609b984c55c027e32c9f0d38d0 (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
#include <Arduino.h>

#define LED_PIN 4
#define POT_PIN 2

#define POT_JITTER_THRESHOLD 10

int potValue = 0;

void SetupTimer()
{
  GCLK->GENDIV.reg = GCLK_GENDIV_DIV(1) |          // Divide the 48MHz clock source by divisor 1: 48MHz/1=48MHz
                     GCLK_GENDIV_ID(4);            // Select Generic Clock (GCLK) 4
  while (GCLK->STATUS.bit.SYNCBUSY);               // Wait for synchronization

  GCLK->GENCTRL.reg = GCLK_GENCTRL_IDC |           // Set the duty cycle to 50/50 HIGH/LOW
                      GCLK_GENCTRL_GENEN |         // Enable GCLK4
                      GCLK_GENCTRL_SRC_DFLL48M |   // Set the 48MHz clock source
                      GCLK_GENCTRL_ID(4);          // Select GCLK4
  while (GCLK->STATUS.bit.SYNCBUSY);               // Wait for synchronization

  // Enable the port multiplexer for port D5
  PORT->Group[g_APinDescription[5].ulPort].PINCFG[g_APinDescription[5].ulPin].bit.PMUXEN = 1;

  // Connect the TCC timers to the port outputs - port pins are paired odd PMUO and even PMUXE
  // F & E specify the timers: TCC0, TCC1 and TCC2
  PORT->Group[g_APinDescription[5].ulPort].PMUX[g_APinDescription[5].ulPin >> 1].reg = PORT_PMUX_PMUXO_F;
 
  // Feed GCLK4 to TCC0 and TCC1
  GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN |         // Enable GCLK4 to TCC0 and TCC1
                      GCLK_CLKCTRL_GEN_GCLK4 |     // Select GCLK4
                      GCLK_CLKCTRL_ID_TCC0_TCC1;   // Feed GCLK4 to TCC0 and TCC1
  while (GCLK->STATUS.bit.SYNCBUSY);                // Wait for synchronization 

  TCC0->WAVE.reg = TCC_WAVE_WAVEGEN_NPWM;          // Single slope PWM operation         
  while (TCC0->SYNCBUSY.bit.WAVE);                 // Wait for synchronization
 
  TCC0->PER.reg = 4799;                            // Set the frequency of the PWM on TCC0 to 10kHz
  while (TCC0->SYNCBUSY.bit.PER);                  // Wait for synchronization

  TCC0->CC[2].reg = 2399;                          // TCC0 CC2 - 50% duty-cycle on D10
  while (TCC0->SYNCBUSY.bit.CC2);                  // Wait for synchronization
  TCC0->CC[3].reg = 2399;                          // TCC0 CC3 - 50% duty-cycle on D12
  while (TCC0->SYNCBUSY.bit.CC3);                  // Wait for synchronization
 
  // Divide the 48MHz signal by 1 giving 48MHz (20.83ns) TCC0 timer tick and enable the timer
  TCC0->CTRLA.reg |= TCC_CTRLA_PRESCALER_DIV1 |    // Divide GCLK4 by 1
                     TCC_CTRLA_ENABLE;             // Enable the TCC0 output
  while (TCC0->SYNCBUSY.bit.ENABLE);               // Wait for synchronization

  //Stop TCC0 counter on MCU initialization (stepper initially stopped)
  //TCC0->CTRLBSET.reg = TCC_CTRLBSET_CMD_STOP;    // Force the TCC0 timer to STOP
  //while (TCC0->SYNCBUSY.bit.CTRLB);              // Wait for synchronization
}

void StopTimer()
{
  //Stop TCC0 counter on MCU initialization (stepper initially stopped)
  TCC0->CTRLBSET.reg = TCC_CTRLBSET_CMD_STOP;           // Force the TCC0 timer to STOP
  while (TCC0->SYNCBUSY.bit.CTRLB);                     // Wait for synchronization
}

void RestartTimer()
{
  // put your main code here, to run repeatedly:
  TCC0->CTRLBSET.reg = TCC_CTRLBSET_CMD_RETRIGGER;      // Force the TCC0 timer to START
  while (TCC0->SYNCBUSY.bit.CTRLB);                     // Wait for synchronization
}

uint32_t stepperFrequencyDivisor = 4799;             //Sets the starting frequency equal to 1hz

void SetFrequencyOutput(uint16_t frequency)
{
  stepperFrequencyDivisor = round(48000000 / frequency);
  
  TCC0->PERB.reg = stepperFrequencyDivisor - 1;         // Set the starting frequency of the PWM on TCC0 to 1Hz
  while (TCC0->SYNCBUSY.bit.PERB);                      // Wait for synchronization
  
  TCC0->CCB[1].reg = (stepperFrequencyDivisor / 2) - 1; // TCC0 CC2 - 50% duty-cycle
  while (TCC0->SYNCBUSY.bit.CCB2);                      // Wait for synchronization
}

void SetMotorOutput(uint16_t rpm)
{
  const float stepperHzToRPM = 1;                      //6.67hz runs the stepper at 1 RPM
  SetFrequencyOutput(rpm * stepperHzToRPM);
}

void setup()
{
  SetupTimer();
}

void loop()
{
  /*int newPotValue = analogRead(POT_PIN);
  if (abs(newPotValue - potValue) > POT_JITTER_THRESHOLD)
  {
    potValue = newPotValue;
    SetFrequencyOutput(map(potValue, 0, 1023, 0, 20000));
  }*/
  for(uint8_t i = 0; i <= 20; i++)
  {
    SetFrequencyOutput(i * 1000);
    delay(10000);
  }
  for(uint8_t i = 20; i >= 0; i--)
  {
    SetFrequencyOutput(i * 1000);
    delay(10000);
  }
}