forked from seishuku/TeensyCNC
-
Notifications
You must be signed in to change notification settings - Fork 1
/
pwm.c
80 lines (66 loc) · 2.66 KB
/
pwm.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
// TeensyCNC
// Copyright 2016 Matt Williams
//
// Motor PWM channel setup and duty cycle setting
#include "MK20D10.h"
void PWM_Init (void) {
// Enable module clock
SIM->SCGC6 |= SIM_SCGC6_FTM0_MASK;
// Set up mode register
FTM0->MODE = FTM_MODE_FAULTM(0x00) | FTM_MODE_WPDIS_MASK;
// Clear status and control register
FTM0->SC = FTM_SC_CLKS(0x00) | FTM_SC_PS(0x00);
// Clear counter initial register
FTM0->CNTIN = FTM_CNTIN_INIT(0x00);
// Reset counter register
FTM0->CNT = FTM_CNT_COUNT(0x00);
// Clear channel status and control registers
FTM0->CONTROLS[0].CnSC = 0x00U;
FTM0->CONTROLS[1].CnSC = 0x00U;
FTM0->CONTROLS[2].CnSC = 0x00U;
FTM0->CONTROLS[3].CnSC = 0x00U;
FTM0->CONTROLS[4].CnSC = 0x00U;
FTM0->CONTROLS[5].CnSC = 0x00U;
FTM0->CONTROLS[6].CnSC = 0x00U;
FTM0->CONTROLS[7].CnSC = 0x00U;
// Set up modulo register
// Bus clock / FTM0_MOD = PWM Freq
// Bus clock / PWM Freq = FTM0_MOD
// 36MHz / 1440 = 25KHz (0.04ms)
// 36MHz / 900 = 40KHz (0.025ms)
// 36MHz / 288 = 125KHz (0.008ms)
FTM0->MOD = FTM_MOD_MOD(900 - 1);
// Set up channel status and control register
FTM0->CONTROLS[0].CnSC = FTM_CnSC_MSB_MASK | FTM_CnSC_ELSB_MASK | FTM_CnSC_ELSA_MASK;
// Set up channel value register
FTM0->CONTROLS[0].CnV = FTM_CnV_VAL(0x00);
// Set up channel status and control register
FTM0->CONTROLS[1].CnSC = FTM_CnSC_MSB_MASK | FTM_CnSC_ELSB_MASK | FTM_CnSC_ELSA_MASK;
// Set up channel value register
FTM0->CONTROLS[1].CnV = FTM_CnV_VAL(0x00);
// Set up channel status and control register
FTM0->CONTROLS[5].CnSC = FTM_CnSC_MSB_MASK | FTM_CnSC_ELSB_MASK | FTM_CnSC_ELSA_MASK;
// Set up channel value register
FTM0->CONTROLS[5].CnV = FTM_CnV_VAL(0x00);
// Set up channel status and control register
FTM0->CONTROLS[6].CnSC = FTM_CnSC_MSB_MASK | FTM_CnSC_ELSB_MASK | FTM_CnSC_ELSA_MASK;
// Set up channel value register
FTM0->CONTROLS[6].CnV = FTM_CnV_VAL(0x00);
// Set up pin muxes
PORTC->PCR[1] = (PORTC->PCR[1] & ~(PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x03))) | PORT_PCR_MUX(0x04);
PORTC->PCR[2] = (PORTC->PCR[2] & ~(PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x03))) | PORT_PCR_MUX(0x04);
PORTD->PCR[5] = (PORTD->PCR[5] & ~(PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x03))) | PORT_PCR_MUX(0x04);
PORTD->PCR[6] = (PORTD->PCR[6] & ~(PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x03))) | PORT_PCR_MUX(0x04);
// Set up status and control register
FTM0->SC = FTM_SC_CLKS(0x01) | FTM_SC_PS(0x01);
}
void PWM_SetRatio (uint8_t Channel, uint16_t Ratio) {
uint16_t Period, Duty;
Period = FTM0->MOD + 1;
if (Period == 0) {
Duty = Ratio;
} else {
Duty = ((Period * Ratio) + 0x8000U) >> 0x10U;
}
FTM0->CONTROLS[Channel].CnV = Duty;
}