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
|
||||
|
||||
// Peripheral abstraction layer for the atsamd21g18.
|
||||
// Peripheral abstraction layer for the atsamd21.
|
||||
//
|
||||
// Datasheet:
|
||||
// http://ww1.microchip.com/downloads/en/DeviceDoc/SAMD21-Family-DataSheet-DS40001882D.pdf
|
||||
|
@ -16,16 +16,45 @@ const CPU_FREQUENCY = 48000000
|
|||
type GPIOMode uint8
|
||||
|
||||
const (
|
||||
GPIO_INPUT = 0
|
||||
GPIO_OUTPUT = 1
|
||||
GPIO_ANALOG = 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.
|
||||
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)
|
||||
} 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)
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче