Implement PWM interface for SAMD21 (#157)
* machine/atsamd21: implement PWM interface for all pins that support it * machine/atsamd21: correct PWM channel mapping for pin PA18 * machine/atsamd21: move clock init into InitPWM() to hopefully save power
Этот коммит содержится в:
родитель
7461c298dd
коммит
19b4476cbb
2 изменённых файлов: 428 добавлений и 220 удалений
|
@ -4,20 +4,20 @@ package machine
|
||||||
|
|
||||||
// GPIO Pins
|
// GPIO Pins
|
||||||
const (
|
const (
|
||||||
D0 = 11 // UART0 RX: SERCOM0/PAD[3]
|
D0 = 11 // UART0 RX
|
||||||
D1 = 10 // UART0 TX: SERCOM0/PAD[2]
|
D1 = 10 // UART0 TX
|
||||||
D2 = 14
|
D2 = 14
|
||||||
D3 = 9
|
D3 = 9 // PWM available
|
||||||
D4 = 8
|
D4 = 8 // PWM available
|
||||||
D5 = 15
|
D5 = 15 // PWM available
|
||||||
D6 = 20
|
D6 = 20 // PWM available
|
||||||
D7 = 21
|
D7 = 21
|
||||||
D8 = 6
|
D8 = 6 // PWM available
|
||||||
D9 = 7
|
D9 = 7 // PWM available
|
||||||
D10 = 18 // UART1 TX(1): SERCOM1/PAD[2] can be used for UART1 TX
|
D10 = 18 // can be used for PWM or UART1 RX
|
||||||
D11 = 16 // UART1 TX(2): SERCOM1/PAD[0] can be used for UART1 TX
|
D11 = 16 // can be used for PWM or UART1 TX
|
||||||
D12 = 19
|
D12 = 19 // PWM available
|
||||||
D13 = 17
|
D13 = 17 // PWM available
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -32,6 +32,6 @@ const (
|
||||||
|
|
||||||
// I2C pins
|
// I2C pins
|
||||||
const (
|
const (
|
||||||
SDA_PIN = 22 // // SDA: SERCOM3/PAD[0]
|
SDA_PIN = 22 // SDA: SERCOM3/PAD[0]
|
||||||
SCL_PIN = 23 // // SCL: SERCOM3/PAD[1]
|
SCL_PIN = 23 // SCL: SERCOM3/PAD[1]
|
||||||
)
|
)
|
||||||
|
|
|
@ -77,224 +77,22 @@ func (p GPIO) Set(high bool) {
|
||||||
|
|
||||||
// getPMux returns the value for the correct PMUX register for this pin.
|
// getPMux returns the value for the correct PMUX register for this pin.
|
||||||
func (p GPIO) getPMux() sam.RegValue8 {
|
func (p GPIO) getPMux() sam.RegValue8 {
|
||||||
pin := p.Pin >> 1
|
return getPMux(p.Pin)
|
||||||
switch pin {
|
|
||||||
case 0:
|
|
||||||
return sam.PORT.PMUX0_0
|
|
||||||
case 1:
|
|
||||||
return sam.PORT.PMUX0_1
|
|
||||||
case 2:
|
|
||||||
return sam.PORT.PMUX0_2
|
|
||||||
case 3:
|
|
||||||
return sam.PORT.PMUX0_3
|
|
||||||
case 4:
|
|
||||||
return sam.PORT.PMUX0_4
|
|
||||||
case 5:
|
|
||||||
return sam.PORT.PMUX0_5
|
|
||||||
case 6:
|
|
||||||
return sam.PORT.PMUX0_6
|
|
||||||
case 7:
|
|
||||||
return sam.PORT.PMUX0_7
|
|
||||||
case 8:
|
|
||||||
return sam.PORT.PMUX0_8
|
|
||||||
case 9:
|
|
||||||
return sam.PORT.PMUX0_9
|
|
||||||
case 10:
|
|
||||||
return sam.PORT.PMUX0_10
|
|
||||||
case 11:
|
|
||||||
return sam.PORT.PMUX0_11
|
|
||||||
case 12:
|
|
||||||
return sam.PORT.PMUX0_12
|
|
||||||
case 13:
|
|
||||||
return sam.PORT.PMUX0_13
|
|
||||||
case 14:
|
|
||||||
return sam.PORT.PMUX0_14
|
|
||||||
case 15:
|
|
||||||
return sam.PORT.PMUX0_15
|
|
||||||
default:
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// setPMux sets the value for the correct PMUX register for this pin.
|
// setPMux sets the value for the correct PMUX register for this pin.
|
||||||
func (p GPIO) setPMux(val sam.RegValue8) {
|
func (p GPIO) setPMux(val sam.RegValue8) {
|
||||||
pin := p.Pin >> 1
|
setPMux(p.Pin, val)
|
||||||
switch pin {
|
|
||||||
case 0:
|
|
||||||
sam.PORT.PMUX0_0 = val
|
|
||||||
case 1:
|
|
||||||
sam.PORT.PMUX0_1 = val
|
|
||||||
case 2:
|
|
||||||
sam.PORT.PMUX0_2 = val
|
|
||||||
case 3:
|
|
||||||
sam.PORT.PMUX0_3 = val
|
|
||||||
case 4:
|
|
||||||
sam.PORT.PMUX0_4 = val
|
|
||||||
case 5:
|
|
||||||
sam.PORT.PMUX0_5 = val
|
|
||||||
case 6:
|
|
||||||
sam.PORT.PMUX0_6 = val
|
|
||||||
case 7:
|
|
||||||
sam.PORT.PMUX0_7 = val
|
|
||||||
case 8:
|
|
||||||
sam.PORT.PMUX0_8 = val
|
|
||||||
case 9:
|
|
||||||
sam.PORT.PMUX0_9 = val
|
|
||||||
case 10:
|
|
||||||
sam.PORT.PMUX0_10 = val
|
|
||||||
case 11:
|
|
||||||
sam.PORT.PMUX0_11 = val
|
|
||||||
case 12:
|
|
||||||
sam.PORT.PMUX0_12 = val
|
|
||||||
case 13:
|
|
||||||
sam.PORT.PMUX0_13 = val
|
|
||||||
case 14:
|
|
||||||
sam.PORT.PMUX0_14 = val
|
|
||||||
case 15:
|
|
||||||
sam.PORT.PMUX0_15 = val
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// getPinCfg returns the value for the correct PINCFG register for this pin.
|
// getPinCfg returns the value for the correct PINCFG register for this pin.
|
||||||
func (p GPIO) getPinCfg() sam.RegValue8 {
|
func (p GPIO) getPinCfg() sam.RegValue8 {
|
||||||
switch p.Pin {
|
return getPinCfg(p.Pin)
|
||||||
case 0:
|
|
||||||
return sam.PORT.PINCFG0_0
|
|
||||||
case 1:
|
|
||||||
return sam.PORT.PINCFG0_1
|
|
||||||
case 2:
|
|
||||||
return sam.PORT.PINCFG0_2
|
|
||||||
case 3:
|
|
||||||
return sam.PORT.PINCFG0_3
|
|
||||||
case 4:
|
|
||||||
return sam.PORT.PINCFG0_4
|
|
||||||
case 5:
|
|
||||||
return sam.PORT.PINCFG0_5
|
|
||||||
case 6:
|
|
||||||
return sam.PORT.PINCFG0_6
|
|
||||||
case 7:
|
|
||||||
return sam.PORT.PINCFG0_7
|
|
||||||
case 8:
|
|
||||||
return sam.PORT.PINCFG0_8
|
|
||||||
case 9:
|
|
||||||
return sam.PORT.PINCFG0_9
|
|
||||||
case 10:
|
|
||||||
return sam.PORT.PINCFG0_10
|
|
||||||
case 11:
|
|
||||||
return sam.PORT.PINCFG0_11
|
|
||||||
case 12:
|
|
||||||
return sam.PORT.PINCFG0_12
|
|
||||||
case 13:
|
|
||||||
return sam.PORT.PINCFG0_13
|
|
||||||
case 14:
|
|
||||||
return sam.PORT.PINCFG0_14
|
|
||||||
case 15:
|
|
||||||
return sam.PORT.PINCFG0_15
|
|
||||||
case 16:
|
|
||||||
return sam.PORT.PINCFG0_16
|
|
||||||
case 17:
|
|
||||||
return sam.PORT.PINCFG0_17
|
|
||||||
case 18:
|
|
||||||
return sam.PORT.PINCFG0_18
|
|
||||||
case 19:
|
|
||||||
return sam.PORT.PINCFG0_19
|
|
||||||
case 20:
|
|
||||||
return sam.PORT.PINCFG0_20
|
|
||||||
case 21:
|
|
||||||
return sam.PORT.PINCFG0_21
|
|
||||||
case 22:
|
|
||||||
return sam.PORT.PINCFG0_22
|
|
||||||
case 23:
|
|
||||||
return sam.PORT.PINCFG0_23
|
|
||||||
case 24:
|
|
||||||
return sam.PORT.PINCFG0_24
|
|
||||||
case 25:
|
|
||||||
return sam.PORT.PINCFG0_25
|
|
||||||
case 26:
|
|
||||||
return sam.PORT.PINCFG0_26
|
|
||||||
case 27:
|
|
||||||
return sam.PORT.PINCFG0_27
|
|
||||||
case 28:
|
|
||||||
return sam.PORT.PINCFG0_28
|
|
||||||
case 29:
|
|
||||||
return sam.PORT.PINCFG0_29
|
|
||||||
case 30:
|
|
||||||
return sam.PORT.PINCFG0_30
|
|
||||||
case 31:
|
|
||||||
return sam.PORT.PINCFG0_31
|
|
||||||
default:
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// setPinCfg sets the value for the correct PINCFG register for this pin.
|
// setPinCfg sets the value for the correct PINCFG register for this pin.
|
||||||
func (p GPIO) setPinCfg(val sam.RegValue8) {
|
func (p GPIO) setPinCfg(val sam.RegValue8) {
|
||||||
switch p.Pin {
|
setPinCfg(p.Pin, val)
|
||||||
case 0:
|
|
||||||
sam.PORT.PINCFG0_0 = val
|
|
||||||
case 1:
|
|
||||||
sam.PORT.PINCFG0_1 = val
|
|
||||||
case 2:
|
|
||||||
sam.PORT.PINCFG0_2 = val
|
|
||||||
case 3:
|
|
||||||
sam.PORT.PINCFG0_3 = val
|
|
||||||
case 4:
|
|
||||||
sam.PORT.PINCFG0_4 = val
|
|
||||||
case 5:
|
|
||||||
sam.PORT.PINCFG0_5 = val
|
|
||||||
case 6:
|
|
||||||
sam.PORT.PINCFG0_6 = val
|
|
||||||
case 7:
|
|
||||||
sam.PORT.PINCFG0_7 = val
|
|
||||||
case 8:
|
|
||||||
sam.PORT.PINCFG0_8 = val
|
|
||||||
case 9:
|
|
||||||
sam.PORT.PINCFG0_9 = val
|
|
||||||
case 10:
|
|
||||||
sam.PORT.PINCFG0_10 = val
|
|
||||||
case 11:
|
|
||||||
sam.PORT.PINCFG0_11 = val
|
|
||||||
case 12:
|
|
||||||
sam.PORT.PINCFG0_12 = val
|
|
||||||
case 13:
|
|
||||||
sam.PORT.PINCFG0_13 = val
|
|
||||||
case 14:
|
|
||||||
sam.PORT.PINCFG0_14 = val
|
|
||||||
case 15:
|
|
||||||
sam.PORT.PINCFG0_15 = val
|
|
||||||
case 16:
|
|
||||||
sam.PORT.PINCFG0_16 = val
|
|
||||||
case 17:
|
|
||||||
sam.PORT.PINCFG0_17 = val
|
|
||||||
case 18:
|
|
||||||
sam.PORT.PINCFG0_18 = val
|
|
||||||
case 19:
|
|
||||||
sam.PORT.PINCFG0_19 = val
|
|
||||||
case 20:
|
|
||||||
sam.PORT.PINCFG0_20 = val
|
|
||||||
case 21:
|
|
||||||
sam.PORT.PINCFG0_21 = val
|
|
||||||
case 22:
|
|
||||||
sam.PORT.PINCFG0_22 = val
|
|
||||||
case 23:
|
|
||||||
sam.PORT.PINCFG0_23 = val
|
|
||||||
case 24:
|
|
||||||
sam.PORT.PINCFG0_24 = val
|
|
||||||
case 25:
|
|
||||||
sam.PORT.PINCFG0_25 = val
|
|
||||||
case 26:
|
|
||||||
sam.PORT.PINCFG0_26 = val
|
|
||||||
case 27:
|
|
||||||
sam.PORT.PINCFG0_27 = val
|
|
||||||
case 28:
|
|
||||||
sam.PORT.PINCFG0_28 = val
|
|
||||||
case 29:
|
|
||||||
sam.PORT.PINCFG0_29 = val
|
|
||||||
case 30:
|
|
||||||
sam.PORT.PINCFG0_30 = val
|
|
||||||
case 31:
|
|
||||||
sam.PORT.PINCFG0_31 = val
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// UART on the SAMD21.
|
// UART on the SAMD21.
|
||||||
|
@ -698,3 +496,413 @@ func (i2c I2C) readByte() byte {
|
||||||
}
|
}
|
||||||
return byte(i2c.Bus.DATA)
|
return byte(i2c.Bus.DATA)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PWM
|
||||||
|
const period = 0xFFFF
|
||||||
|
|
||||||
|
// InitPWM initializes the PWM interface.
|
||||||
|
func InitPWM() {
|
||||||
|
// turn on timer clocks used for PWM
|
||||||
|
sam.PM.APBCMASK |= sam.PM_APBCMASK_TCC0_ | sam.PM_APBCMASK_TCC1_ | sam.PM_APBCMASK_TCC2_
|
||||||
|
|
||||||
|
// Use GCLK0 for TCC0/TCC1
|
||||||
|
sam.GCLK.CLKCTRL = sam.RegValue16((sam.GCLK_CLKCTRL_ID_TCC0_TCC1 << sam.GCLK_CLKCTRL_ID_Pos) |
|
||||||
|
(sam.GCLK_CLKCTRL_GEN_GCLK0 << sam.GCLK_CLKCTRL_GEN_Pos) |
|
||||||
|
sam.GCLK_CLKCTRL_CLKEN)
|
||||||
|
for (sam.GCLK.STATUS & sam.GCLK_STATUS_SYNCBUSY) > 0 {
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use GCLK0 for TCC2/TC3
|
||||||
|
sam.GCLK.CLKCTRL = sam.RegValue16((sam.GCLK_CLKCTRL_ID_TCC2_TC3 << sam.GCLK_CLKCTRL_ID_Pos) |
|
||||||
|
(sam.GCLK_CLKCTRL_GEN_GCLK0 << sam.GCLK_CLKCTRL_GEN_Pos) |
|
||||||
|
sam.GCLK_CLKCTRL_CLKEN)
|
||||||
|
for (sam.GCLK.STATUS & sam.GCLK_STATUS_SYNCBUSY) > 0 {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure configures a PWM pin for output.
|
||||||
|
func (pwm PWM) Configure() {
|
||||||
|
// figure out which TCCX timer for this pin
|
||||||
|
timer := pwm.getTimer()
|
||||||
|
|
||||||
|
// disable timer
|
||||||
|
timer.CTRLA &^= sam.TCC_CTRLA_ENABLE
|
||||||
|
// Wait for synchronization
|
||||||
|
for (timer.SYNCBUSY & sam.TCC_SYNCBUSY_ENABLE) > 0 {
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use "Normal PWM" (single-slope PWM)
|
||||||
|
timer.WAVE |= sam.TCC_WAVE_WAVEGEN_NPWM
|
||||||
|
// Wait for synchronization
|
||||||
|
for (timer.SYNCBUSY & sam.TCC_SYNCBUSY_WAVE) > 0 {
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the period (the number to count to (TOP) before resetting timer)
|
||||||
|
//TCC0->PER.reg = period;
|
||||||
|
timer.PER = period
|
||||||
|
// Wait for synchronization
|
||||||
|
for (timer.SYNCBUSY & sam.TCC_SYNCBUSY_PER) > 0 {
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set pin as output
|
||||||
|
sam.PORT.DIRSET0 = (1 << pwm.Pin)
|
||||||
|
// Set pin to low
|
||||||
|
sam.PORT.OUTCLR0 = (1 << pwm.Pin)
|
||||||
|
|
||||||
|
// Enable the port multiplexer for pin
|
||||||
|
pwm.setPinCfg(sam.PORT_PINCFG0_PMUXEN)
|
||||||
|
|
||||||
|
// Connect TCCX timer to pin.
|
||||||
|
// we normally use the F channel aka ALT
|
||||||
|
pwmConfig := GPIO_PWM_ALT
|
||||||
|
|
||||||
|
// in the case of PA6 or PA7 we have to use E channel
|
||||||
|
if pwm.Pin == 6 || pwm.Pin == 7 {
|
||||||
|
pwmConfig = GPIO_PWM
|
||||||
|
}
|
||||||
|
|
||||||
|
if pwm.Pin&1 > 0 {
|
||||||
|
// odd pin, so save the even pins
|
||||||
|
val := pwm.getPMux() & sam.PORT_PMUX0_PMUXE_Msk
|
||||||
|
pwm.setPMux(val | sam.RegValue8(pwmConfig<<sam.PORT_PMUX0_PMUXO_Pos))
|
||||||
|
} else {
|
||||||
|
// even pin, so save the odd pins
|
||||||
|
val := pwm.getPMux() & sam.PORT_PMUX0_PMUXO_Msk
|
||||||
|
pwm.setPMux(val | sam.RegValue8(pwmConfig<<sam.PORT_PMUX0_PMUXE_Pos))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set turns on the duty cycle for a PWM pin using the provided value.
|
||||||
|
func (pwm PWM) Set(value uint16) {
|
||||||
|
// figure out which TCCX timer for this pin
|
||||||
|
timer := pwm.getTimer()
|
||||||
|
|
||||||
|
// disable output
|
||||||
|
timer.CTRLA &^= sam.TCC_CTRLA_ENABLE
|
||||||
|
|
||||||
|
// Wait for synchronization
|
||||||
|
for (timer.SYNCBUSY & sam.TCC_SYNCBUSY_ENABLE) > 0 {
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set PWM signal to output duty cycle
|
||||||
|
pwm.setChannel(sam.RegValue(value))
|
||||||
|
|
||||||
|
// Wait for synchronization on all channels
|
||||||
|
for (timer.SYNCBUSY & (sam.TCC_SYNCBUSY_CC0 |
|
||||||
|
sam.TCC_SYNCBUSY_CC1 |
|
||||||
|
sam.TCC_SYNCBUSY_CC2 |
|
||||||
|
sam.TCC_SYNCBUSY_CC3)) > 0 {
|
||||||
|
}
|
||||||
|
|
||||||
|
// enable
|
||||||
|
timer.CTRLA |= sam.TCC_CTRLA_ENABLE
|
||||||
|
// Wait for synchronization
|
||||||
|
for (timer.SYNCBUSY & sam.TCC_SYNCBUSY_ENABLE) > 0 {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// getPMux returns the value for the correct PMUX register for this pin.
|
||||||
|
func (pwm PWM) getPMux() sam.RegValue8 {
|
||||||
|
return getPMux(pwm.Pin)
|
||||||
|
}
|
||||||
|
|
||||||
|
// setPMux sets the value for the correct PMUX register for this pin.
|
||||||
|
func (pwm PWM) setPMux(val sam.RegValue8) {
|
||||||
|
setPMux(pwm.Pin, val)
|
||||||
|
}
|
||||||
|
|
||||||
|
// getPinCfg returns the value for the correct PINCFG register for this pin.
|
||||||
|
func (pwm PWM) getPinCfg() sam.RegValue8 {
|
||||||
|
return getPinCfg(pwm.Pin)
|
||||||
|
}
|
||||||
|
|
||||||
|
// setPinCfg sets the value for the correct PINCFG register for this pin.
|
||||||
|
func (pwm PWM) setPinCfg(val sam.RegValue8) {
|
||||||
|
setPinCfg(pwm.Pin, val)
|
||||||
|
}
|
||||||
|
|
||||||
|
// getPMux returns the value for the correct PMUX register for this pin.
|
||||||
|
func getPMux(p uint8) sam.RegValue8 {
|
||||||
|
pin := p >> 1
|
||||||
|
switch pin {
|
||||||
|
case 0:
|
||||||
|
return sam.PORT.PMUX0_0
|
||||||
|
case 1:
|
||||||
|
return sam.PORT.PMUX0_1
|
||||||
|
case 2:
|
||||||
|
return sam.PORT.PMUX0_2
|
||||||
|
case 3:
|
||||||
|
return sam.PORT.PMUX0_3
|
||||||
|
case 4:
|
||||||
|
return sam.PORT.PMUX0_4
|
||||||
|
case 5:
|
||||||
|
return sam.PORT.PMUX0_5
|
||||||
|
case 6:
|
||||||
|
return sam.PORT.PMUX0_6
|
||||||
|
case 7:
|
||||||
|
return sam.PORT.PMUX0_7
|
||||||
|
case 8:
|
||||||
|
return sam.PORT.PMUX0_8
|
||||||
|
case 9:
|
||||||
|
return sam.PORT.PMUX0_9
|
||||||
|
case 10:
|
||||||
|
return sam.PORT.PMUX0_10
|
||||||
|
case 11:
|
||||||
|
return sam.PORT.PMUX0_11
|
||||||
|
case 12:
|
||||||
|
return sam.PORT.PMUX0_12
|
||||||
|
case 13:
|
||||||
|
return sam.PORT.PMUX0_13
|
||||||
|
case 14:
|
||||||
|
return sam.PORT.PMUX0_14
|
||||||
|
case 15:
|
||||||
|
return sam.PORT.PMUX0_15
|
||||||
|
default:
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// setPMux sets the value for the correct PMUX register for this pin.
|
||||||
|
func setPMux(p uint8, val sam.RegValue8) {
|
||||||
|
pin := p >> 1
|
||||||
|
switch pin {
|
||||||
|
case 0:
|
||||||
|
sam.PORT.PMUX0_0 = val
|
||||||
|
case 1:
|
||||||
|
sam.PORT.PMUX0_1 = val
|
||||||
|
case 2:
|
||||||
|
sam.PORT.PMUX0_2 = val
|
||||||
|
case 3:
|
||||||
|
sam.PORT.PMUX0_3 = val
|
||||||
|
case 4:
|
||||||
|
sam.PORT.PMUX0_4 = val
|
||||||
|
case 5:
|
||||||
|
sam.PORT.PMUX0_5 = val
|
||||||
|
case 6:
|
||||||
|
sam.PORT.PMUX0_6 = val
|
||||||
|
case 7:
|
||||||
|
sam.PORT.PMUX0_7 = val
|
||||||
|
case 8:
|
||||||
|
sam.PORT.PMUX0_8 = val
|
||||||
|
case 9:
|
||||||
|
sam.PORT.PMUX0_9 = val
|
||||||
|
case 10:
|
||||||
|
sam.PORT.PMUX0_10 = val
|
||||||
|
case 11:
|
||||||
|
sam.PORT.PMUX0_11 = val
|
||||||
|
case 12:
|
||||||
|
sam.PORT.PMUX0_12 = val
|
||||||
|
case 13:
|
||||||
|
sam.PORT.PMUX0_13 = val
|
||||||
|
case 14:
|
||||||
|
sam.PORT.PMUX0_14 = val
|
||||||
|
case 15:
|
||||||
|
sam.PORT.PMUX0_15 = val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// getPinCfg returns the value for the correct PINCFG register for this pin.
|
||||||
|
func getPinCfg(p uint8) sam.RegValue8 {
|
||||||
|
switch p {
|
||||||
|
case 0:
|
||||||
|
return sam.PORT.PINCFG0_0
|
||||||
|
case 1:
|
||||||
|
return sam.PORT.PINCFG0_1
|
||||||
|
case 2:
|
||||||
|
return sam.PORT.PINCFG0_2
|
||||||
|
case 3:
|
||||||
|
return sam.PORT.PINCFG0_3
|
||||||
|
case 4:
|
||||||
|
return sam.PORT.PINCFG0_4
|
||||||
|
case 5:
|
||||||
|
return sam.PORT.PINCFG0_5
|
||||||
|
case 6:
|
||||||
|
return sam.PORT.PINCFG0_6
|
||||||
|
case 7:
|
||||||
|
return sam.PORT.PINCFG0_7
|
||||||
|
case 8:
|
||||||
|
return sam.PORT.PINCFG0_8
|
||||||
|
case 9:
|
||||||
|
return sam.PORT.PINCFG0_9
|
||||||
|
case 10:
|
||||||
|
return sam.PORT.PINCFG0_10
|
||||||
|
case 11:
|
||||||
|
return sam.PORT.PINCFG0_11
|
||||||
|
case 12:
|
||||||
|
return sam.PORT.PINCFG0_12
|
||||||
|
case 13:
|
||||||
|
return sam.PORT.PINCFG0_13
|
||||||
|
case 14:
|
||||||
|
return sam.PORT.PINCFG0_14
|
||||||
|
case 15:
|
||||||
|
return sam.PORT.PINCFG0_15
|
||||||
|
case 16:
|
||||||
|
return sam.PORT.PINCFG0_16
|
||||||
|
case 17:
|
||||||
|
return sam.PORT.PINCFG0_17
|
||||||
|
case 18:
|
||||||
|
return sam.PORT.PINCFG0_18
|
||||||
|
case 19:
|
||||||
|
return sam.PORT.PINCFG0_19
|
||||||
|
case 20:
|
||||||
|
return sam.PORT.PINCFG0_20
|
||||||
|
case 21:
|
||||||
|
return sam.PORT.PINCFG0_21
|
||||||
|
case 22:
|
||||||
|
return sam.PORT.PINCFG0_22
|
||||||
|
case 23:
|
||||||
|
return sam.PORT.PINCFG0_23
|
||||||
|
case 24:
|
||||||
|
return sam.PORT.PINCFG0_24
|
||||||
|
case 25:
|
||||||
|
return sam.PORT.PINCFG0_25
|
||||||
|
case 26:
|
||||||
|
return sam.PORT.PINCFG0_26
|
||||||
|
case 27:
|
||||||
|
return sam.PORT.PINCFG0_27
|
||||||
|
case 28:
|
||||||
|
return sam.PORT.PINCFG0_28
|
||||||
|
case 29:
|
||||||
|
return sam.PORT.PINCFG0_29
|
||||||
|
case 30:
|
||||||
|
return sam.PORT.PINCFG0_30
|
||||||
|
case 31:
|
||||||
|
return sam.PORT.PINCFG0_31
|
||||||
|
default:
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// setPinCfg sets the value for the correct PINCFG register for this pin.
|
||||||
|
func setPinCfg(p uint8, val sam.RegValue8) {
|
||||||
|
switch p {
|
||||||
|
case 0:
|
||||||
|
sam.PORT.PINCFG0_0 = val
|
||||||
|
case 1:
|
||||||
|
sam.PORT.PINCFG0_1 = val
|
||||||
|
case 2:
|
||||||
|
sam.PORT.PINCFG0_2 = val
|
||||||
|
case 3:
|
||||||
|
sam.PORT.PINCFG0_3 = val
|
||||||
|
case 4:
|
||||||
|
sam.PORT.PINCFG0_4 = val
|
||||||
|
case 5:
|
||||||
|
sam.PORT.PINCFG0_5 = val
|
||||||
|
case 6:
|
||||||
|
sam.PORT.PINCFG0_6 = val
|
||||||
|
case 7:
|
||||||
|
sam.PORT.PINCFG0_7 = val
|
||||||
|
case 8:
|
||||||
|
sam.PORT.PINCFG0_8 = val
|
||||||
|
case 9:
|
||||||
|
sam.PORT.PINCFG0_9 = val
|
||||||
|
case 10:
|
||||||
|
sam.PORT.PINCFG0_10 = val
|
||||||
|
case 11:
|
||||||
|
sam.PORT.PINCFG0_11 = val
|
||||||
|
case 12:
|
||||||
|
sam.PORT.PINCFG0_12 = val
|
||||||
|
case 13:
|
||||||
|
sam.PORT.PINCFG0_13 = val
|
||||||
|
case 14:
|
||||||
|
sam.PORT.PINCFG0_14 = val
|
||||||
|
case 15:
|
||||||
|
sam.PORT.PINCFG0_15 = val
|
||||||
|
case 16:
|
||||||
|
sam.PORT.PINCFG0_16 = val
|
||||||
|
case 17:
|
||||||
|
sam.PORT.PINCFG0_17 = val
|
||||||
|
case 18:
|
||||||
|
sam.PORT.PINCFG0_18 = val
|
||||||
|
case 19:
|
||||||
|
sam.PORT.PINCFG0_19 = val
|
||||||
|
case 20:
|
||||||
|
sam.PORT.PINCFG0_20 = val
|
||||||
|
case 21:
|
||||||
|
sam.PORT.PINCFG0_21 = val
|
||||||
|
case 22:
|
||||||
|
sam.PORT.PINCFG0_22 = val
|
||||||
|
case 23:
|
||||||
|
sam.PORT.PINCFG0_23 = val
|
||||||
|
case 24:
|
||||||
|
sam.PORT.PINCFG0_24 = val
|
||||||
|
case 25:
|
||||||
|
sam.PORT.PINCFG0_25 = val
|
||||||
|
case 26:
|
||||||
|
sam.PORT.PINCFG0_26 = val
|
||||||
|
case 27:
|
||||||
|
sam.PORT.PINCFG0_27 = val
|
||||||
|
case 28:
|
||||||
|
sam.PORT.PINCFG0_28 = val
|
||||||
|
case 29:
|
||||||
|
sam.PORT.PINCFG0_29 = val
|
||||||
|
case 30:
|
||||||
|
sam.PORT.PINCFG0_30 = val
|
||||||
|
case 31:
|
||||||
|
sam.PORT.PINCFG0_31 = val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// getTimer returns the timer to be used for PWM on this pin
|
||||||
|
func (pwm PWM) getTimer() *sam.TCC_Type {
|
||||||
|
switch pwm.Pin {
|
||||||
|
case 6:
|
||||||
|
return sam.TCC1
|
||||||
|
case 7:
|
||||||
|
return sam.TCC1
|
||||||
|
case 8:
|
||||||
|
return sam.TCC1
|
||||||
|
case 9:
|
||||||
|
return sam.TCC1
|
||||||
|
case 14:
|
||||||
|
return sam.TCC0
|
||||||
|
case 15:
|
||||||
|
return sam.TCC0
|
||||||
|
case 16:
|
||||||
|
return sam.TCC0
|
||||||
|
case 17:
|
||||||
|
return sam.TCC0
|
||||||
|
case 18:
|
||||||
|
return sam.TCC0
|
||||||
|
case 19:
|
||||||
|
return sam.TCC0
|
||||||
|
case 20:
|
||||||
|
return sam.TCC0
|
||||||
|
case 21:
|
||||||
|
return sam.TCC0
|
||||||
|
default:
|
||||||
|
return nil // not supported on this pin
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// setChannel sets the value for the correct channel for PWM on this pin
|
||||||
|
func (pwm PWM) setChannel(val sam.RegValue) {
|
||||||
|
switch pwm.Pin {
|
||||||
|
case 6:
|
||||||
|
pwm.getTimer().CC0 = val
|
||||||
|
case 7:
|
||||||
|
pwm.getTimer().CC1 = val
|
||||||
|
case 8:
|
||||||
|
pwm.getTimer().CC0 = val
|
||||||
|
case 9:
|
||||||
|
pwm.getTimer().CC1 = val
|
||||||
|
case 14:
|
||||||
|
pwm.getTimer().CC0 = val
|
||||||
|
case 15:
|
||||||
|
pwm.getTimer().CC1 = val
|
||||||
|
case 16:
|
||||||
|
pwm.getTimer().CC2 = val
|
||||||
|
case 17:
|
||||||
|
pwm.getTimer().CC3 = val
|
||||||
|
case 18:
|
||||||
|
pwm.getTimer().CC2 = val
|
||||||
|
case 19:
|
||||||
|
pwm.getTimer().CC3 = val
|
||||||
|
case 20:
|
||||||
|
pwm.getTimer().CC2 = val
|
||||||
|
case 21:
|
||||||
|
pwm.getTimer().CC3 = val
|
||||||
|
default:
|
||||||
|
return // not supported on this pin
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче