machine/atsamd21: improve GPIO config to support all 32 pins on PORTA as well as correct handling for OUTPUT and SERCOM pin modes
Signed-off-by: Ron Evans <ron@hybridgroup.com>
Этот коммит содержится в:
родитель
f89c695c8c
коммит
8cbbbb0e76
1 изменённых файлов: 256 добавлений и 5 удалений
|
@ -1,6 +1,6 @@
|
||||||
// +build sam,atsamd21g18a
|
// +build sam,atsamd21g18a
|
||||||
|
|
||||||
// Peripheral abstraction layer for the atsamd21g18.
|
// Peripheral abstraction layer for the atsamd21.
|
||||||
//
|
//
|
||||||
// Datasheet:
|
// Datasheet:
|
||||||
// http://ww1.microchip.com/downloads/en/DeviceDoc/SAMD21-Family-DataSheet-DS40001882D.pdf
|
// http://ww1.microchip.com/downloads/en/DeviceDoc/SAMD21-Family-DataSheet-DS40001882D.pdf
|
||||||
|
@ -16,16 +16,45 @@ const CPU_FREQUENCY = 48000000
|
||||||
type GPIOMode uint8
|
type GPIOMode uint8
|
||||||
|
|
||||||
const (
|
const (
|
||||||
GPIO_INPUT = 0
|
GPIO_ANALOG = 1
|
||||||
GPIO_OUTPUT = 1
|
GPIO_SERCOM = 2
|
||||||
|
GPIO_SERCOM_ALT = 3
|
||||||
|
GPIO_TIMER = 4
|
||||||
|
GPIO_TIMER_ALT = 5
|
||||||
|
GPIO_COM = 6
|
||||||
|
GPIO_AC_CLK = 7
|
||||||
|
GPIO_DIGITAL = 8
|
||||||
|
GPIO_INPUT = 9
|
||||||
|
GPIO_INPUT_PULLUP = 10
|
||||||
|
GPIO_OUTPUT = 11
|
||||||
|
GPIO_PWM = GPIO_TIMER
|
||||||
|
GPIO_PWM_ALT = GPIO_TIMER_ALT
|
||||||
)
|
)
|
||||||
|
|
||||||
// Configure this pin with the given configuration.
|
// Configure this pin with the given configuration.
|
||||||
func (p GPIO) Configure(config GPIOConfig) {
|
func (p GPIO) Configure(config GPIOConfig) {
|
||||||
if config.Mode == GPIO_OUTPUT { // set output bit
|
switch config.Mode {
|
||||||
|
case GPIO_OUTPUT:
|
||||||
sam.PORT.DIRSET0 = (1 << p.Pin)
|
sam.PORT.DIRSET0 = (1 << p.Pin)
|
||||||
} else {
|
// output is also set to input enable so pin can read back its own value
|
||||||
|
p.setPinCfg(sam.PORT_PINCFG0_INEN)
|
||||||
|
|
||||||
|
case GPIO_INPUT:
|
||||||
sam.PORT.DIRCLR0 = (1 << p.Pin)
|
sam.PORT.DIRCLR0 = (1 << p.Pin)
|
||||||
|
p.setPinCfg(sam.PORT_PINCFG0_INEN)
|
||||||
|
|
||||||
|
case GPIO_SERCOM:
|
||||||
|
if p.Pin&1 > 0 {
|
||||||
|
// odd pin, so save the even pins
|
||||||
|
val := p.getPMux() & sam.PORT_PMUX0_PMUXE_Msk
|
||||||
|
p.setPMux(val | (GPIO_SERCOM << sam.PORT_PMUX0_PMUXO_Pos))
|
||||||
|
} else {
|
||||||
|
// even pin, so save the odd pins
|
||||||
|
val := p.getPMux() & sam.PORT_PMUX0_PMUXO_Msk
|
||||||
|
p.setPMux(val | (GPIO_SERCOM << sam.PORT_PMUX0_PMUXE_Pos))
|
||||||
|
}
|
||||||
|
// enable port config
|
||||||
|
p.setPinCfg(sam.PORT_PINCFG0_PMUXEN | sam.PORT_PINCFG0_DRVSTR)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,3 +72,225 @@ func (p GPIO) Set(high bool) {
|
||||||
sam.PORT.OUTCLR0 = (1 << p.Pin)
|
sam.PORT.OUTCLR0 = (1 << p.Pin)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getPMux returns the value for the correct PMUX register for this pin.
|
||||||
|
func (p GPIO) getPMux() sam.RegValue8 {
|
||||||
|
pin := p.Pin >> 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 (p GPIO) setPMux(val sam.RegValue8) {
|
||||||
|
pin := p.Pin >> 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 (p GPIO) getPinCfg() sam.RegValue8 {
|
||||||
|
switch 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.
|
||||||
|
func (p GPIO) setPinCfg(val sam.RegValue8) {
|
||||||
|
switch p.Pin {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче