[Board] Adafruit Trinket (#333)
* Add support for Adafruit Trinket-M0 board
Этот коммит содержится в:
родитель
e0cf74e638
коммит
fc2ed2bdd0
10 изменённых файлов: 1103 добавлений и 612 удалений
|
@ -79,6 +79,7 @@ commands:
|
|||
- run: tinygo build -size short -o test.elf -target=pca10056 examples/blinky1
|
||||
- run: tinygo build -size short -o test.elf -target=pca10056 examples/blinky2
|
||||
- run: tinygo build -size short -o test.elf -target=itsybitsy-m0 examples/blinky1
|
||||
- run: tinygo build -size short -o test.elf -target=trinket-m0 examples/blinky1
|
||||
- run: tinygo build -size short -o test.elf -target=circuitplay-express examples/blinky1
|
||||
- run: tinygo build -size short -o test.elf -target=stm32f4disco examples/blinky1
|
||||
- run: tinygo build -size short -o test.elf -target=stm32f4disco examples/blinky2
|
||||
|
|
73
src/machine/board_trinket.go
Обычный файл
73
src/machine/board_trinket.go
Обычный файл
|
@ -0,0 +1,73 @@
|
|||
// +build sam,atsamd21,trinket_m0
|
||||
|
||||
package machine
|
||||
|
||||
import "device/sam"
|
||||
|
||||
// GPIO Pins
|
||||
const (
|
||||
D0 = PA08 // PWM available
|
||||
D1 = PA02
|
||||
D2 = PA09 // PWM available
|
||||
D3 = PA07 // PWM available / UART0 RX
|
||||
D4 = PA06 // PWM available / UART0 TX
|
||||
D13 = PA10 // LED
|
||||
)
|
||||
|
||||
// Analog pins
|
||||
const (
|
||||
A0 = D1
|
||||
A1 = D2
|
||||
A2 = D0
|
||||
A3 = D3
|
||||
A4 = D4
|
||||
)
|
||||
|
||||
const (
|
||||
LED = D13
|
||||
)
|
||||
|
||||
// UART0 aka USBCDC pins
|
||||
const (
|
||||
USBCDC_DM_PIN = PA24
|
||||
USBCDC_DP_PIN = PA25
|
||||
)
|
||||
|
||||
// UART1 pins
|
||||
const (
|
||||
UART_TX_PIN = D4
|
||||
UART_RX_PIN = D3
|
||||
)
|
||||
|
||||
// SPI pins
|
||||
const (
|
||||
SPI0_SCK_PIN = D3
|
||||
SPI0_MOSI_PIN = D4
|
||||
SPI0_MISO_PIN = D2
|
||||
)
|
||||
|
||||
// SPI on the Trinket M0.
|
||||
var (
|
||||
SPI0 = SPI{Bus: sam.SERCOM0_SPI}
|
||||
)
|
||||
|
||||
// I2C pins
|
||||
const (
|
||||
SDA_PIN = D0 // SDA
|
||||
SCL_PIN = D2 // SCL
|
||||
)
|
||||
|
||||
// I2C on the Trinket M0.
|
||||
var (
|
||||
I2C0 = I2C{Bus: sam.SERCOM2_I2CM,
|
||||
SDA: SDA_PIN,
|
||||
SCL: SCL_PIN,
|
||||
PinMode: GPIO_SERCOM_ALT}
|
||||
)
|
||||
|
||||
// I2S pins
|
||||
const (
|
||||
I2S_SCK_PIN = PA10
|
||||
I2S_SD_PIN = PA08
|
||||
I2S_WS_PIN = 0xff // TODO: figure out what this is on Trinket M0.
|
||||
)
|
|
@ -105,151 +105,6 @@ const (
|
|||
PB31 = 63
|
||||
)
|
||||
|
||||
// Configure this pin with the given configuration.
|
||||
func (p GPIO) Configure(config GPIOConfig) {
|
||||
switch config.Mode {
|
||||
case GPIO_OUTPUT:
|
||||
if p.Pin < 32 {
|
||||
sam.PORT.DIRSET0 = (1 << p.Pin)
|
||||
// output is also set to input enable so pin can read back its own value
|
||||
p.setPinCfg(sam.PORT_PINCFG0_INEN)
|
||||
} else {
|
||||
sam.PORT.DIRSET1 = (1 << (p.Pin - 32))
|
||||
// output is also set to input enable so pin can read back its own value
|
||||
p.setPinCfg(sam.PORT_PINCFG0_INEN)
|
||||
}
|
||||
|
||||
case GPIO_INPUT:
|
||||
if p.Pin < 32 {
|
||||
sam.PORT.DIRCLR0 = (1 << p.Pin)
|
||||
p.setPinCfg(sam.PORT_PINCFG0_INEN)
|
||||
} else {
|
||||
sam.PORT.DIRCLR1 = (1<<p.Pin - 32)
|
||||
p.setPinCfg(sam.PORT_PINCFG0_INEN)
|
||||
}
|
||||
|
||||
case GPIO_INPUT_PULLDOWN:
|
||||
if p.Pin < 32 {
|
||||
sam.PORT.DIRCLR0 = (1 << p.Pin)
|
||||
sam.PORT.OUTCLR0 = (1 << p.Pin)
|
||||
p.setPinCfg(sam.PORT_PINCFG0_INEN | sam.PORT_PINCFG0_PULLEN)
|
||||
} else {
|
||||
sam.PORT.DIRCLR1 = (1<<p.Pin - 32)
|
||||
sam.PORT.OUTCLR1 = (1<<p.Pin - 32)
|
||||
p.setPinCfg(sam.PORT_PINCFG0_INEN | sam.PORT_PINCFG0_PULLEN)
|
||||
}
|
||||
|
||||
case GPIO_INPUT_PULLUP:
|
||||
if p.Pin < 32 {
|
||||
sam.PORT.DIRCLR0 = (1 << p.Pin)
|
||||
sam.PORT.OUTSET0 = (1 << p.Pin)
|
||||
p.setPinCfg(sam.PORT_PINCFG0_INEN | sam.PORT_PINCFG0_PULLEN)
|
||||
} else {
|
||||
sam.PORT.DIRCLR1 = (1<<p.Pin - 32)
|
||||
sam.PORT.OUTSET1 = (1<<p.Pin - 32)
|
||||
p.setPinCfg(sam.PORT_PINCFG0_INEN | sam.PORT_PINCFG0_PULLEN)
|
||||
}
|
||||
|
||||
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 | sam.PORT_PINCFG0_INEN)
|
||||
|
||||
case GPIO_SERCOM_ALT:
|
||||
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_ALT << 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_ALT << sam.PORT_PMUX0_PMUXE_Pos))
|
||||
}
|
||||
// enable port config
|
||||
p.setPinCfg(sam.PORT_PINCFG0_PMUXEN | sam.PORT_PINCFG0_DRVSTR)
|
||||
|
||||
case GPIO_COM:
|
||||
if p.Pin&1 > 0 {
|
||||
// odd pin, so save the even pins
|
||||
val := p.getPMux() & sam.PORT_PMUX0_PMUXE_Msk
|
||||
p.setPMux(val | (GPIO_COM << 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_COM << sam.PORT_PMUX0_PMUXE_Pos))
|
||||
}
|
||||
// enable port config
|
||||
p.setPinCfg(sam.PORT_PINCFG0_PMUXEN)
|
||||
case GPIO_ANALOG:
|
||||
if p.Pin&1 > 0 {
|
||||
// odd pin, so save the even pins
|
||||
val := p.getPMux() & sam.PORT_PMUX0_PMUXE_Msk
|
||||
p.setPMux(val | (GPIO_ANALOG << 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_COM << sam.PORT_PMUX0_PMUXE_Pos))
|
||||
}
|
||||
// enable port config
|
||||
p.setPinCfg(sam.PORT_PINCFG0_PMUXEN | sam.PORT_PINCFG0_DRVSTR)
|
||||
}
|
||||
}
|
||||
|
||||
// Get returns the current value of a GPIO pin.
|
||||
func (p GPIO) Get() bool {
|
||||
if p.Pin < 32 {
|
||||
return (sam.PORT.IN0>>p.Pin)&1 > 0
|
||||
} else {
|
||||
return (sam.PORT.IN1>>(p.Pin-32))&1 > 0
|
||||
}
|
||||
}
|
||||
|
||||
// Set the pin to high or low.
|
||||
// Warning: only use this on an output pin!
|
||||
func (p GPIO) Set(high bool) {
|
||||
if p.Pin < 32 {
|
||||
if high {
|
||||
sam.PORT.OUTSET0 = (1 << p.Pin)
|
||||
} else {
|
||||
sam.PORT.OUTCLR0 = (1 << p.Pin)
|
||||
}
|
||||
} else {
|
||||
if high {
|
||||
sam.PORT.OUTSET1 = (1 << (p.Pin - 32))
|
||||
} else {
|
||||
sam.PORT.OUTCLR1 = (1 << (p.Pin - 32))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return the register and mask to enable a given GPIO pin. This can be used to
|
||||
// implement bit-banged drivers.
|
||||
func (p GPIO) PortMaskSet() (*uint32, uint32) {
|
||||
if p.Pin < 32 {
|
||||
return (*uint32)(&sam.PORT.OUTSET0), 1 << p.Pin
|
||||
} else {
|
||||
return (*uint32)(&sam.PORT.OUTSET1), 1 << (p.Pin - 32)
|
||||
}
|
||||
}
|
||||
|
||||
// Return the register and mask to disable a given port. This can be used to
|
||||
// implement bit-banged drivers.
|
||||
func (p GPIO) PortMaskClear() (*uint32, uint32) {
|
||||
if p.Pin < 32 {
|
||||
return (*uint32)(&sam.PORT.OUTCLR0), 1 << p.Pin
|
||||
} else {
|
||||
return (*uint32)(&sam.PORT.OUTCLR1), 1 << (p.Pin - 32)
|
||||
}
|
||||
}
|
||||
|
||||
// getPMux returns the value for the correct PMUX register for this pin.
|
||||
func (p GPIO) getPMux() sam.RegValue8 {
|
||||
return getPMux(p.Pin)
|
||||
|
@ -1265,420 +1120,6 @@ 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
|
||||
case 16:
|
||||
return sam.RegValue8(sam.PORT.PMUX1_0>>0) & 0xff
|
||||
case 17:
|
||||
return sam.RegValue8(sam.PORT.PMUX1_0>>8) & 0xff
|
||||
case 18:
|
||||
return sam.RegValue8(sam.PORT.PMUX1_0>>16) & 0xff
|
||||
case 19:
|
||||
return sam.RegValue8(sam.PORT.PMUX1_0>>24) & 0xff
|
||||
case 20:
|
||||
return sam.RegValue8(sam.PORT.PMUX1_4>>0) & 0xff
|
||||
case 21:
|
||||
return sam.RegValue8(sam.PORT.PMUX1_4>>8) & 0xff
|
||||
case 22:
|
||||
return sam.RegValue8(sam.PORT.PMUX1_4>>16) & 0xff
|
||||
case 23:
|
||||
return sam.RegValue8(sam.PORT.PMUX1_4>>24) & 0xff
|
||||
case 24:
|
||||
return sam.RegValue8(sam.PORT.PMUX1_8>>0) & 0xff
|
||||
case 25:
|
||||
return sam.RegValue8(sam.PORT.PMUX1_8>>8) & 0xff
|
||||
case 26:
|
||||
return sam.RegValue8(sam.PORT.PMUX1_8>>16) & 0xff
|
||||
case 27:
|
||||
return sam.RegValue8(sam.PORT.PMUX1_8>>24) & 0xff
|
||||
case 28:
|
||||
return sam.RegValue8(sam.PORT.PMUX1_12>>0) & 0xff
|
||||
case 29:
|
||||
return sam.RegValue8(sam.PORT.PMUX1_12>>8) & 0xff
|
||||
case 30:
|
||||
return sam.RegValue8(sam.PORT.PMUX1_12>>16) & 0xff
|
||||
case 31:
|
||||
return sam.RegValue8(sam.PORT.PMUX1_12>>24) & 0xff
|
||||
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
|
||||
case 16:
|
||||
sam.PORT.PMUX1_0 = (sam.PORT.PMUX1_0 &^ (0xff << 0)) | (sam.RegValue(val) << 0)
|
||||
case 17:
|
||||
sam.PORT.PMUX1_0 = (sam.PORT.PMUX1_0 &^ (0xff << 8)) | (sam.RegValue(val) << 8)
|
||||
case 18:
|
||||
sam.PORT.PMUX1_0 = (sam.PORT.PMUX1_0 &^ (0xff << 16)) | (sam.RegValue(val) << 16)
|
||||
case 19:
|
||||
sam.PORT.PMUX1_0 = (sam.PORT.PMUX1_0 &^ (0xff << 24)) | (sam.RegValue(val) << 24)
|
||||
case 20:
|
||||
sam.PORT.PMUX1_4 = (sam.PORT.PMUX1_4 &^ (0xff << 0)) | (sam.RegValue(val) << 0)
|
||||
case 21:
|
||||
sam.PORT.PMUX1_4 = (sam.PORT.PMUX1_4 &^ (0xff << 8)) | (sam.RegValue(val) << 8)
|
||||
case 22:
|
||||
sam.PORT.PMUX1_4 = (sam.PORT.PMUX1_4 &^ (0xff << 16)) | (sam.RegValue(val) << 16)
|
||||
case 23:
|
||||
sam.PORT.PMUX1_4 = (sam.PORT.PMUX1_4 &^ (0xff << 24)) | (sam.RegValue(val) << 24)
|
||||
case 24:
|
||||
sam.PORT.PMUX1_8 = (sam.PORT.PMUX1_8 &^ (0xff << 0)) | (sam.RegValue(val) << 0)
|
||||
case 25:
|
||||
sam.PORT.PMUX1_8 = (sam.PORT.PMUX1_8 &^ (0xff << 8)) | (sam.RegValue(val) << 8)
|
||||
case 26:
|
||||
sam.PORT.PMUX1_8 = (sam.PORT.PMUX1_8 &^ (0xff << 16)) | (sam.RegValue(val) << 16)
|
||||
case 27:
|
||||
sam.PORT.PMUX1_8 = (sam.PORT.PMUX1_8 &^ (0xff << 24)) | (sam.RegValue(val) << 24)
|
||||
case 28:
|
||||
sam.PORT.PMUX1_12 = (sam.PORT.PMUX1_12 &^ (0xff << 0)) | (sam.RegValue(val) << 0)
|
||||
case 29:
|
||||
sam.PORT.PMUX1_12 = (sam.PORT.PMUX1_12 &^ (0xff << 8)) | (sam.RegValue(val) << 8)
|
||||
case 30:
|
||||
sam.PORT.PMUX1_12 = (sam.PORT.PMUX1_12 &^ (0xff << 16)) | (sam.RegValue(val) << 16)
|
||||
case 31:
|
||||
sam.PORT.PMUX1_12 = (sam.PORT.PMUX1_12 &^ (0xff << 24)) | (sam.RegValue(val) << 24)
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
case 32: // PB00
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_0>>0) & 0xff
|
||||
case 33: // PB01
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_0>>8) & 0xff
|
||||
case 34: // PB02
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_0>>16) & 0xff
|
||||
case 35: // PB03
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_0>>24) & 0xff
|
||||
case 37: // PB04
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_4>>0) & 0xff
|
||||
case 38: // PB05
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_4>>8) & 0xff
|
||||
case 39: // PB06
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_4>>16) & 0xff
|
||||
case 40: // PB07
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_4>>24) & 0xff
|
||||
case 41: // PB08
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_8>>0) & 0xff
|
||||
case 42: // PB09
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_8>>8) & 0xff
|
||||
case 43: // PB10
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_8>>16) & 0xff
|
||||
case 44: // PB11
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_8>>24) & 0xff
|
||||
case 45: // PB12
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_12>>0) & 0xff
|
||||
case 46: // PB13
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_12>>8) & 0xff
|
||||
case 47: // PB14
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_12>>16) & 0xff
|
||||
case 48: // PB15
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_12>>24) & 0xff
|
||||
case 49: // PB16
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_16>>0) & 0xff
|
||||
case 50: // PB17
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_16>>8) & 0xff
|
||||
case 51: // PB18
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_16>>16) & 0xff
|
||||
case 52: // PB19
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_16>>24) & 0xff
|
||||
case 53: // PB20
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_20>>0) & 0xff
|
||||
case 54: // PB21
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_20>>8) & 0xff
|
||||
case 55: // PB22
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_20>>16) & 0xff
|
||||
case 56: // PB23
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_20>>24) & 0xff
|
||||
case 57: // PB24
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_24>>0) & 0xff
|
||||
case 58: // PB25
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_24>>8) & 0xff
|
||||
case 59: // PB26
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_24>>16) & 0xff
|
||||
case 60: // PB27
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_24>>24) & 0xff
|
||||
case 61: // PB28
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_28>>0) & 0xff
|
||||
case 62: // PB29
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_28>>8) & 0xff
|
||||
case 63: // PB30
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_28>>16) & 0xff
|
||||
case 64: // PB31
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_28>>24) & 0xff
|
||||
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
|
||||
case 32: // PB00
|
||||
sam.PORT.PINCFG1_0 = (sam.PORT.PINCFG1_0 &^ (0xff << 0)) | (sam.RegValue(val) << 0)
|
||||
case 33: // PB01
|
||||
sam.PORT.PINCFG1_0 = (sam.PORT.PINCFG1_0 &^ (0xff << 8)) | (sam.RegValue(val) << 8)
|
||||
case 34: // PB02
|
||||
sam.PORT.PINCFG1_0 = (sam.PORT.PINCFG1_0 &^ (0xff << 16)) | (sam.RegValue(val) << 16)
|
||||
case 35: // PB03
|
||||
sam.PORT.PINCFG1_0 = (sam.PORT.PINCFG1_0 &^ (0xff << 24)) | (sam.RegValue(val) << 24)
|
||||
case 36: // PB04
|
||||
sam.PORT.PINCFG1_4 = (sam.PORT.PINCFG1_4 &^ (0xff << 0)) | (sam.RegValue(val) << 0)
|
||||
case 37: // PB05
|
||||
sam.PORT.PINCFG1_4 = (sam.PORT.PINCFG1_4 &^ (0xff << 8)) | (sam.RegValue(val) << 8)
|
||||
case 38: // PB06
|
||||
sam.PORT.PINCFG1_4 = (sam.PORT.PINCFG1_4 &^ (0xff << 16)) | (sam.RegValue(val) << 16)
|
||||
case 39: // PB07
|
||||
sam.PORT.PINCFG1_4 = (sam.PORT.PINCFG1_4 &^ (0xff << 24)) | (sam.RegValue(val) << 24)
|
||||
case 40: // PB08
|
||||
sam.PORT.PINCFG1_8 = (sam.PORT.PINCFG1_8 &^ (0xff << 0)) | (sam.RegValue(val) << 0)
|
||||
case 41: // PB09
|
||||
sam.PORT.PINCFG1_8 = (sam.PORT.PINCFG1_8 &^ (0xff << 8)) | (sam.RegValue(val) << 8)
|
||||
case 42: // PB10
|
||||
sam.PORT.PINCFG1_8 = (sam.PORT.PINCFG1_8 &^ (0xff << 16)) | (sam.RegValue(val) << 16)
|
||||
case 43: // PB11
|
||||
sam.PORT.PINCFG1_8 = (sam.PORT.PINCFG1_8 &^ (0xff << 24)) | (sam.RegValue(val) << 24)
|
||||
case 44: // PB12
|
||||
sam.PORT.PINCFG1_12 = (sam.PORT.PINCFG1_12 &^ (0xff << 0)) | (sam.RegValue(val) << 0)
|
||||
case 45: // PB13
|
||||
sam.PORT.PINCFG1_12 = (sam.PORT.PINCFG1_12 &^ (0xff << 8)) | (sam.RegValue(val) << 8)
|
||||
case 46: // PB14
|
||||
sam.PORT.PINCFG1_12 = (sam.PORT.PINCFG1_12 &^ (0xff << 16)) | (sam.RegValue(val) << 16)
|
||||
case 47: // PB15
|
||||
sam.PORT.PINCFG1_12 = (sam.PORT.PINCFG1_12 &^ (0xff << 24)) | (sam.RegValue(val) << 24)
|
||||
case 48: // PB16
|
||||
sam.PORT.PINCFG1_16 = (sam.PORT.PINCFG1_16 &^ (0xff << 0)) | (sam.RegValue(val) << 0)
|
||||
case 49: // PB17
|
||||
sam.PORT.PINCFG1_16 = (sam.PORT.PINCFG1_16 &^ (0xff << 8)) | (sam.RegValue(val) << 8)
|
||||
case 50: // PB18
|
||||
sam.PORT.PINCFG1_16 = (sam.PORT.PINCFG1_16 &^ (0xff << 16)) | (sam.RegValue(val) << 16)
|
||||
case 51: // PB19
|
||||
sam.PORT.PINCFG1_16 = (sam.PORT.PINCFG1_16 &^ (0xff << 24)) | (sam.RegValue(val) << 24)
|
||||
case 52: // PB20
|
||||
sam.PORT.PINCFG1_20 = (sam.PORT.PINCFG1_20 &^ (0xff << 0)) | (sam.RegValue(val) << 0)
|
||||
case 53: // PB21
|
||||
sam.PORT.PINCFG1_20 = (sam.PORT.PINCFG1_20 &^ (0xff << 8)) | (sam.RegValue(val) << 8)
|
||||
case 54: // PB22
|
||||
sam.PORT.PINCFG1_20 = (sam.PORT.PINCFG1_20 &^ (0xff << 16)) | (sam.RegValue(val) << 16)
|
||||
case 55: // PB23
|
||||
sam.PORT.PINCFG1_20 = (sam.PORT.PINCFG1_20 &^ (0xff << 24)) | (sam.RegValue(val) << 24)
|
||||
case 56: // PB24
|
||||
sam.PORT.PINCFG1_24 = (sam.PORT.PINCFG1_24 &^ (0xff << 0)) | (sam.RegValue(val) << 0)
|
||||
case 57: // PB25
|
||||
sam.PORT.PINCFG1_24 = (sam.PORT.PINCFG1_24 &^ (0xff << 8)) | (sam.RegValue(val) << 8)
|
||||
case 58: // PB26
|
||||
sam.PORT.PINCFG1_24 = (sam.PORT.PINCFG1_24 &^ (0xff << 16)) | (sam.RegValue(val) << 16)
|
||||
case 59: // PB27
|
||||
sam.PORT.PINCFG1_24 = (sam.PORT.PINCFG1_24 &^ (0xff << 24)) | (sam.RegValue(val) << 24)
|
||||
case 60: // PB28
|
||||
sam.PORT.PINCFG1_28 = (sam.PORT.PINCFG1_28 &^ (0xff << 0)) | (sam.RegValue(val) << 0)
|
||||
case 61: // PB29
|
||||
sam.PORT.PINCFG1_28 = (sam.PORT.PINCFG1_28 &^ (0xff << 8)) | (sam.RegValue(val) << 8)
|
||||
case 62: // PB30
|
||||
sam.PORT.PINCFG1_28 = (sam.PORT.PINCFG1_28 &^ (0xff << 16)) | (sam.RegValue(val) << 16)
|
||||
case 63: // PB31
|
||||
sam.PORT.PINCFG1_28 = (sam.PORT.PINCFG1_28 &^ (0xff << 24)) | (sam.RegValue(val) << 24)
|
||||
}
|
||||
}
|
||||
|
||||
// getTimer returns the timer to be used for PWM on this pin
|
||||
func (pwm PWM) getTimer() *sam.TCC_Type {
|
||||
switch pwm.Pin {
|
||||
|
|
336
src/machine/machine_atsamd21e18.go
Обычный файл
336
src/machine/machine_atsamd21e18.go
Обычный файл
|
@ -0,0 +1,336 @@
|
|||
// +build sam,atsamd21,atsamd21e18
|
||||
|
||||
// Peripheral abstraction layer for the atsamd21.
|
||||
//
|
||||
// Datasheet:
|
||||
// http://ww1.microchip.com/downloads/en/DeviceDoc/SAMD21-Family-DataSheet-DS40001882D.pdf
|
||||
//
|
||||
package machine
|
||||
|
||||
import (
|
||||
"device/sam"
|
||||
)
|
||||
|
||||
// Return the register and mask to enable a given GPIO pin. This can be used to
|
||||
// implement bit-banged drivers.
|
||||
func (p GPIO) PortMaskSet() (*uint32, uint32) {
|
||||
return (*uint32)(&sam.PORT.OUTSET0), 1 << p.Pin
|
||||
}
|
||||
|
||||
// Return the register and mask to disable a given port. This can be used to
|
||||
// implement bit-banged drivers.
|
||||
func (p GPIO) PortMaskClear() (*uint32, uint32) {
|
||||
return (*uint32)(&sam.PORT.OUTCLR0), 1 << p.Pin
|
||||
}
|
||||
|
||||
// Set the pin to high or low.
|
||||
// Warning: only use this on an output pin!
|
||||
func (p GPIO) Set(high bool) {
|
||||
if high {
|
||||
sam.PORT.OUTSET0 = (1 << p.Pin)
|
||||
} else {
|
||||
sam.PORT.OUTCLR0 = (1 << p.Pin)
|
||||
}
|
||||
}
|
||||
|
||||
// Get returns the current value of a GPIO pin.
|
||||
func (p GPIO) Get() bool {
|
||||
return (sam.PORT.IN0>>p.Pin)&1 > 0
|
||||
}
|
||||
|
||||
// Configure this pin with the given configuration.
|
||||
func (p GPIO) Configure(config GPIOConfig) {
|
||||
switch config.Mode {
|
||||
case GPIO_OUTPUT:
|
||||
sam.PORT.DIRSET0 = (1 << p.Pin)
|
||||
// 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_INPUT_PULLDOWN:
|
||||
sam.PORT.DIRCLR0 = (1 << p.Pin)
|
||||
sam.PORT.OUTCLR0 = (1 << p.Pin)
|
||||
p.setPinCfg(sam.PORT_PINCFG0_INEN | sam.PORT_PINCFG0_PULLEN)
|
||||
|
||||
case GPIO_INPUT_PULLUP:
|
||||
sam.PORT.DIRCLR0 = (1 << p.Pin)
|
||||
sam.PORT.OUTSET0 = (1 << p.Pin)
|
||||
p.setPinCfg(sam.PORT_PINCFG0_INEN | sam.PORT_PINCFG0_PULLEN)
|
||||
|
||||
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 | sam.PORT_PINCFG0_INEN)
|
||||
|
||||
case GPIO_SERCOM_ALT:
|
||||
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_ALT << 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_ALT << sam.PORT_PMUX0_PMUXE_Pos))
|
||||
}
|
||||
// enable port config
|
||||
p.setPinCfg(sam.PORT_PINCFG0_PMUXEN | sam.PORT_PINCFG0_DRVSTR)
|
||||
|
||||
case GPIO_COM:
|
||||
if p.Pin&1 > 0 {
|
||||
// odd pin, so save the even pins
|
||||
val := p.getPMux() & sam.PORT_PMUX0_PMUXE_Msk
|
||||
p.setPMux(val | (GPIO_COM << 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_COM << sam.PORT_PMUX0_PMUXE_Pos))
|
||||
}
|
||||
// enable port config
|
||||
p.setPinCfg(sam.PORT_PINCFG0_PMUXEN)
|
||||
case GPIO_ANALOG:
|
||||
if p.Pin&1 > 0 {
|
||||
// odd pin, so save the even pins
|
||||
val := p.getPMux() & sam.PORT_PMUX0_PMUXE_Msk
|
||||
p.setPMux(val | (GPIO_ANALOG << 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_COM << sam.PORT_PMUX0_PMUXE_Pos))
|
||||
}
|
||||
// enable port config
|
||||
p.setPinCfg(sam.PORT_PINCFG0_PMUXEN | sam.PORT_PINCFG0_DRVSTR)
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
}
|
571
src/machine/machine_atsamd21g18.go
Обычный файл
571
src/machine/machine_atsamd21g18.go
Обычный файл
|
@ -0,0 +1,571 @@
|
|||
// +build sam,atsamd21,atsamd21g18
|
||||
|
||||
// Peripheral abstraction layer for the atsamd21.
|
||||
//
|
||||
// Datasheet:
|
||||
// http://ww1.microchip.com/downloads/en/DeviceDoc/SAMD21-Family-DataSheet-DS40001882D.pdf
|
||||
//
|
||||
package machine
|
||||
|
||||
import (
|
||||
"device/sam"
|
||||
)
|
||||
|
||||
// Return the register and mask to enable a given GPIO pin. This can be used to
|
||||
// implement bit-banged drivers.
|
||||
func (p GPIO) PortMaskSet() (*uint32, uint32) {
|
||||
if p.Pin < 32 {
|
||||
return (*uint32)(&sam.PORT.OUTSET0), 1 << p.Pin
|
||||
} else {
|
||||
return (*uint32)(&sam.PORT.OUTSET1), 1 << (p.Pin - 32)
|
||||
}
|
||||
}
|
||||
|
||||
// Return the register and mask to disable a given port. This can be used to
|
||||
// implement bit-banged drivers.
|
||||
func (p GPIO) PortMaskClear() (*uint32, uint32) {
|
||||
if p.Pin < 32 {
|
||||
return (*uint32)(&sam.PORT.OUTCLR0), 1 << p.Pin
|
||||
} else {
|
||||
return (*uint32)(&sam.PORT.OUTCLR1), 1 << (p.Pin - 32)
|
||||
}
|
||||
}
|
||||
|
||||
// Set the pin to high or low.
|
||||
// Warning: only use this on an output pin!
|
||||
func (p GPIO) Set(high bool) {
|
||||
if p.Pin < 32 {
|
||||
if high {
|
||||
sam.PORT.OUTSET0 = (1 << p.Pin)
|
||||
} else {
|
||||
sam.PORT.OUTCLR0 = (1 << p.Pin)
|
||||
}
|
||||
} else {
|
||||
if high {
|
||||
sam.PORT.OUTSET1 = (1 << (p.Pin - 32))
|
||||
} else {
|
||||
sam.PORT.OUTCLR1 = (1 << (p.Pin - 32))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get returns the current value of a GPIO pin.
|
||||
func (p GPIO) Get() bool {
|
||||
if p.Pin < 32 {
|
||||
return (sam.PORT.IN0>>p.Pin)&1 > 0
|
||||
} else {
|
||||
return (sam.PORT.IN1>>(p.Pin-32))&1 > 0
|
||||
}
|
||||
}
|
||||
|
||||
// Configure this pin with the given configuration.
|
||||
func (p GPIO) Configure(config GPIOConfig) {
|
||||
switch config.Mode {
|
||||
case GPIO_OUTPUT:
|
||||
if p.Pin < 32 {
|
||||
sam.PORT.DIRSET0 = (1 << p.Pin)
|
||||
// output is also set to input enable so pin can read back its own value
|
||||
p.setPinCfg(sam.PORT_PINCFG0_INEN)
|
||||
} else {
|
||||
sam.PORT.DIRSET1 = (1 << (p.Pin - 32))
|
||||
// output is also set to input enable so pin can read back its own value
|
||||
p.setPinCfg(sam.PORT_PINCFG0_INEN)
|
||||
}
|
||||
|
||||
case GPIO_INPUT:
|
||||
if p.Pin < 32 {
|
||||
sam.PORT.DIRCLR0 = (1 << p.Pin)
|
||||
p.setPinCfg(sam.PORT_PINCFG0_INEN)
|
||||
} else {
|
||||
sam.PORT.DIRCLR1 = (1<<p.Pin - 32)
|
||||
p.setPinCfg(sam.PORT_PINCFG0_INEN)
|
||||
}
|
||||
|
||||
case GPIO_INPUT_PULLDOWN:
|
||||
if p.Pin < 32 {
|
||||
sam.PORT.DIRCLR0 = (1 << p.Pin)
|
||||
sam.PORT.OUTCLR0 = (1 << p.Pin)
|
||||
p.setPinCfg(sam.PORT_PINCFG0_INEN | sam.PORT_PINCFG0_PULLEN)
|
||||
} else {
|
||||
sam.PORT.DIRCLR1 = (1<<p.Pin - 32)
|
||||
sam.PORT.OUTCLR1 = (1<<p.Pin - 32)
|
||||
p.setPinCfg(sam.PORT_PINCFG0_INEN | sam.PORT_PINCFG0_PULLEN)
|
||||
}
|
||||
|
||||
case GPIO_INPUT_PULLUP:
|
||||
if p.Pin < 32 {
|
||||
sam.PORT.DIRCLR0 = (1 << p.Pin)
|
||||
sam.PORT.OUTSET0 = (1 << p.Pin)
|
||||
p.setPinCfg(sam.PORT_PINCFG0_INEN | sam.PORT_PINCFG0_PULLEN)
|
||||
} else {
|
||||
sam.PORT.DIRCLR1 = (1<<p.Pin - 32)
|
||||
sam.PORT.OUTSET1 = (1<<p.Pin - 32)
|
||||
p.setPinCfg(sam.PORT_PINCFG0_INEN | sam.PORT_PINCFG0_PULLEN)
|
||||
}
|
||||
|
||||
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 | sam.PORT_PINCFG0_INEN)
|
||||
|
||||
case GPIO_SERCOM_ALT:
|
||||
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_ALT << 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_ALT << sam.PORT_PMUX0_PMUXE_Pos))
|
||||
}
|
||||
// enable port config
|
||||
p.setPinCfg(sam.PORT_PINCFG0_PMUXEN | sam.PORT_PINCFG0_DRVSTR)
|
||||
|
||||
case GPIO_COM:
|
||||
if p.Pin&1 > 0 {
|
||||
// odd pin, so save the even pins
|
||||
val := p.getPMux() & sam.PORT_PMUX0_PMUXE_Msk
|
||||
p.setPMux(val | (GPIO_COM << 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_COM << sam.PORT_PMUX0_PMUXE_Pos))
|
||||
}
|
||||
// enable port config
|
||||
p.setPinCfg(sam.PORT_PINCFG0_PMUXEN)
|
||||
case GPIO_ANALOG:
|
||||
if p.Pin&1 > 0 {
|
||||
// odd pin, so save the even pins
|
||||
val := p.getPMux() & sam.PORT_PMUX0_PMUXE_Msk
|
||||
p.setPMux(val | (GPIO_ANALOG << 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_COM << sam.PORT_PMUX0_PMUXE_Pos))
|
||||
}
|
||||
// enable port config
|
||||
p.setPinCfg(sam.PORT_PINCFG0_PMUXEN | sam.PORT_PINCFG0_DRVSTR)
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
case 16:
|
||||
return sam.RegValue8(sam.PORT.PMUX1_0>>0) & 0xff
|
||||
case 17:
|
||||
return sam.RegValue8(sam.PORT.PMUX1_0>>8) & 0xff
|
||||
case 18:
|
||||
return sam.RegValue8(sam.PORT.PMUX1_0>>16) & 0xff
|
||||
case 19:
|
||||
return sam.RegValue8(sam.PORT.PMUX1_0>>24) & 0xff
|
||||
case 20:
|
||||
return sam.RegValue8(sam.PORT.PMUX1_4>>0) & 0xff
|
||||
case 21:
|
||||
return sam.RegValue8(sam.PORT.PMUX1_4>>8) & 0xff
|
||||
case 22:
|
||||
return sam.RegValue8(sam.PORT.PMUX1_4>>16) & 0xff
|
||||
case 23:
|
||||
return sam.RegValue8(sam.PORT.PMUX1_4>>24) & 0xff
|
||||
case 24:
|
||||
return sam.RegValue8(sam.PORT.PMUX1_8>>0) & 0xff
|
||||
case 25:
|
||||
return sam.RegValue8(sam.PORT.PMUX1_8>>8) & 0xff
|
||||
case 26:
|
||||
return sam.RegValue8(sam.PORT.PMUX1_8>>16) & 0xff
|
||||
case 27:
|
||||
return sam.RegValue8(sam.PORT.PMUX1_8>>24) & 0xff
|
||||
case 28:
|
||||
return sam.RegValue8(sam.PORT.PMUX1_12>>0) & 0xff
|
||||
case 29:
|
||||
return sam.RegValue8(sam.PORT.PMUX1_12>>8) & 0xff
|
||||
case 30:
|
||||
return sam.RegValue8(sam.PORT.PMUX1_12>>16) & 0xff
|
||||
case 31:
|
||||
return sam.RegValue8(sam.PORT.PMUX1_12>>24) & 0xff
|
||||
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
|
||||
case 16:
|
||||
sam.PORT.PMUX1_0 = (sam.PORT.PMUX1_0 &^ (0xff << 0)) | (sam.RegValue(val) << 0)
|
||||
case 17:
|
||||
sam.PORT.PMUX1_0 = (sam.PORT.PMUX1_0 &^ (0xff << 8)) | (sam.RegValue(val) << 8)
|
||||
case 18:
|
||||
sam.PORT.PMUX1_0 = (sam.PORT.PMUX1_0 &^ (0xff << 16)) | (sam.RegValue(val) << 16)
|
||||
case 19:
|
||||
sam.PORT.PMUX1_0 = (sam.PORT.PMUX1_0 &^ (0xff << 24)) | (sam.RegValue(val) << 24)
|
||||
case 20:
|
||||
sam.PORT.PMUX1_4 = (sam.PORT.PMUX1_4 &^ (0xff << 0)) | (sam.RegValue(val) << 0)
|
||||
case 21:
|
||||
sam.PORT.PMUX1_4 = (sam.PORT.PMUX1_4 &^ (0xff << 8)) | (sam.RegValue(val) << 8)
|
||||
case 22:
|
||||
sam.PORT.PMUX1_4 = (sam.PORT.PMUX1_4 &^ (0xff << 16)) | (sam.RegValue(val) << 16)
|
||||
case 23:
|
||||
sam.PORT.PMUX1_4 = (sam.PORT.PMUX1_4 &^ (0xff << 24)) | (sam.RegValue(val) << 24)
|
||||
case 24:
|
||||
sam.PORT.PMUX1_8 = (sam.PORT.PMUX1_8 &^ (0xff << 0)) | (sam.RegValue(val) << 0)
|
||||
case 25:
|
||||
sam.PORT.PMUX1_8 = (sam.PORT.PMUX1_8 &^ (0xff << 8)) | (sam.RegValue(val) << 8)
|
||||
case 26:
|
||||
sam.PORT.PMUX1_8 = (sam.PORT.PMUX1_8 &^ (0xff << 16)) | (sam.RegValue(val) << 16)
|
||||
case 27:
|
||||
sam.PORT.PMUX1_8 = (sam.PORT.PMUX1_8 &^ (0xff << 24)) | (sam.RegValue(val) << 24)
|
||||
case 28:
|
||||
sam.PORT.PMUX1_12 = (sam.PORT.PMUX1_12 &^ (0xff << 0)) | (sam.RegValue(val) << 0)
|
||||
case 29:
|
||||
sam.PORT.PMUX1_12 = (sam.PORT.PMUX1_12 &^ (0xff << 8)) | (sam.RegValue(val) << 8)
|
||||
case 30:
|
||||
sam.PORT.PMUX1_12 = (sam.PORT.PMUX1_12 &^ (0xff << 16)) | (sam.RegValue(val) << 16)
|
||||
case 31:
|
||||
sam.PORT.PMUX1_12 = (sam.PORT.PMUX1_12 &^ (0xff << 24)) | (sam.RegValue(val) << 24)
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
case 32: // PB00
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_0>>0) & 0xff
|
||||
case 33: // PB01
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_0>>8) & 0xff
|
||||
case 34: // PB02
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_0>>16) & 0xff
|
||||
case 35: // PB03
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_0>>24) & 0xff
|
||||
case 37: // PB04
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_4>>0) & 0xff
|
||||
case 38: // PB05
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_4>>8) & 0xff
|
||||
case 39: // PB06
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_4>>16) & 0xff
|
||||
case 40: // PB07
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_4>>24) & 0xff
|
||||
case 41: // PB08
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_8>>0) & 0xff
|
||||
case 42: // PB09
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_8>>8) & 0xff
|
||||
case 43: // PB10
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_8>>16) & 0xff
|
||||
case 44: // PB11
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_8>>24) & 0xff
|
||||
case 45: // PB12
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_12>>0) & 0xff
|
||||
case 46: // PB13
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_12>>8) & 0xff
|
||||
case 47: // PB14
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_12>>16) & 0xff
|
||||
case 48: // PB15
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_12>>24) & 0xff
|
||||
case 49: // PB16
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_16>>0) & 0xff
|
||||
case 50: // PB17
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_16>>8) & 0xff
|
||||
case 51: // PB18
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_16>>16) & 0xff
|
||||
case 52: // PB19
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_16>>24) & 0xff
|
||||
case 53: // PB20
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_20>>0) & 0xff
|
||||
case 54: // PB21
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_20>>8) & 0xff
|
||||
case 55: // PB22
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_20>>16) & 0xff
|
||||
case 56: // PB23
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_20>>24) & 0xff
|
||||
case 57: // PB24
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_24>>0) & 0xff
|
||||
case 58: // PB25
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_24>>8) & 0xff
|
||||
case 59: // PB26
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_24>>16) & 0xff
|
||||
case 60: // PB27
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_24>>24) & 0xff
|
||||
case 61: // PB28
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_28>>0) & 0xff
|
||||
case 62: // PB29
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_28>>8) & 0xff
|
||||
case 63: // PB30
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_28>>16) & 0xff
|
||||
case 64: // PB31
|
||||
return sam.RegValue8(sam.PORT.PINCFG1_28>>24) & 0xff
|
||||
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
|
||||
case 32: // PB00
|
||||
sam.PORT.PINCFG1_0 = (sam.PORT.PINCFG1_0 &^ (0xff << 0)) | (sam.RegValue(val) << 0)
|
||||
case 33: // PB01
|
||||
sam.PORT.PINCFG1_0 = (sam.PORT.PINCFG1_0 &^ (0xff << 8)) | (sam.RegValue(val) << 8)
|
||||
case 34: // PB02
|
||||
sam.PORT.PINCFG1_0 = (sam.PORT.PINCFG1_0 &^ (0xff << 16)) | (sam.RegValue(val) << 16)
|
||||
case 35: // PB03
|
||||
sam.PORT.PINCFG1_0 = (sam.PORT.PINCFG1_0 &^ (0xff << 24)) | (sam.RegValue(val) << 24)
|
||||
case 36: // PB04
|
||||
sam.PORT.PINCFG1_4 = (sam.PORT.PINCFG1_4 &^ (0xff << 0)) | (sam.RegValue(val) << 0)
|
||||
case 37: // PB05
|
||||
sam.PORT.PINCFG1_4 = (sam.PORT.PINCFG1_4 &^ (0xff << 8)) | (sam.RegValue(val) << 8)
|
||||
case 38: // PB06
|
||||
sam.PORT.PINCFG1_4 = (sam.PORT.PINCFG1_4 &^ (0xff << 16)) | (sam.RegValue(val) << 16)
|
||||
case 39: // PB07
|
||||
sam.PORT.PINCFG1_4 = (sam.PORT.PINCFG1_4 &^ (0xff << 24)) | (sam.RegValue(val) << 24)
|
||||
case 40: // PB08
|
||||
sam.PORT.PINCFG1_8 = (sam.PORT.PINCFG1_8 &^ (0xff << 0)) | (sam.RegValue(val) << 0)
|
||||
case 41: // PB09
|
||||
sam.PORT.PINCFG1_8 = (sam.PORT.PINCFG1_8 &^ (0xff << 8)) | (sam.RegValue(val) << 8)
|
||||
case 42: // PB10
|
||||
sam.PORT.PINCFG1_8 = (sam.PORT.PINCFG1_8 &^ (0xff << 16)) | (sam.RegValue(val) << 16)
|
||||
case 43: // PB11
|
||||
sam.PORT.PINCFG1_8 = (sam.PORT.PINCFG1_8 &^ (0xff << 24)) | (sam.RegValue(val) << 24)
|
||||
case 44: // PB12
|
||||
sam.PORT.PINCFG1_12 = (sam.PORT.PINCFG1_12 &^ (0xff << 0)) | (sam.RegValue(val) << 0)
|
||||
case 45: // PB13
|
||||
sam.PORT.PINCFG1_12 = (sam.PORT.PINCFG1_12 &^ (0xff << 8)) | (sam.RegValue(val) << 8)
|
||||
case 46: // PB14
|
||||
sam.PORT.PINCFG1_12 = (sam.PORT.PINCFG1_12 &^ (0xff << 16)) | (sam.RegValue(val) << 16)
|
||||
case 47: // PB15
|
||||
sam.PORT.PINCFG1_12 = (sam.PORT.PINCFG1_12 &^ (0xff << 24)) | (sam.RegValue(val) << 24)
|
||||
case 48: // PB16
|
||||
sam.PORT.PINCFG1_16 = (sam.PORT.PINCFG1_16 &^ (0xff << 0)) | (sam.RegValue(val) << 0)
|
||||
case 49: // PB17
|
||||
sam.PORT.PINCFG1_16 = (sam.PORT.PINCFG1_16 &^ (0xff << 8)) | (sam.RegValue(val) << 8)
|
||||
case 50: // PB18
|
||||
sam.PORT.PINCFG1_16 = (sam.PORT.PINCFG1_16 &^ (0xff << 16)) | (sam.RegValue(val) << 16)
|
||||
case 51: // PB19
|
||||
sam.PORT.PINCFG1_16 = (sam.PORT.PINCFG1_16 &^ (0xff << 24)) | (sam.RegValue(val) << 24)
|
||||
case 52: // PB20
|
||||
sam.PORT.PINCFG1_20 = (sam.PORT.PINCFG1_20 &^ (0xff << 0)) | (sam.RegValue(val) << 0)
|
||||
case 53: // PB21
|
||||
sam.PORT.PINCFG1_20 = (sam.PORT.PINCFG1_20 &^ (0xff << 8)) | (sam.RegValue(val) << 8)
|
||||
case 54: // PB22
|
||||
sam.PORT.PINCFG1_20 = (sam.PORT.PINCFG1_20 &^ (0xff << 16)) | (sam.RegValue(val) << 16)
|
||||
case 55: // PB23
|
||||
sam.PORT.PINCFG1_20 = (sam.PORT.PINCFG1_20 &^ (0xff << 24)) | (sam.RegValue(val) << 24)
|
||||
case 56: // PB24
|
||||
sam.PORT.PINCFG1_24 = (sam.PORT.PINCFG1_24 &^ (0xff << 0)) | (sam.RegValue(val) << 0)
|
||||
case 57: // PB25
|
||||
sam.PORT.PINCFG1_24 = (sam.PORT.PINCFG1_24 &^ (0xff << 8)) | (sam.RegValue(val) << 8)
|
||||
case 58: // PB26
|
||||
sam.PORT.PINCFG1_24 = (sam.PORT.PINCFG1_24 &^ (0xff << 16)) | (sam.RegValue(val) << 16)
|
||||
case 59: // PB27
|
||||
sam.PORT.PINCFG1_24 = (sam.PORT.PINCFG1_24 &^ (0xff << 24)) | (sam.RegValue(val) << 24)
|
||||
case 60: // PB28
|
||||
sam.PORT.PINCFG1_28 = (sam.PORT.PINCFG1_28 &^ (0xff << 0)) | (sam.RegValue(val) << 0)
|
||||
case 61: // PB29
|
||||
sam.PORT.PINCFG1_28 = (sam.PORT.PINCFG1_28 &^ (0xff << 8)) | (sam.RegValue(val) << 8)
|
||||
case 62: // PB30
|
||||
sam.PORT.PINCFG1_28 = (sam.PORT.PINCFG1_28 &^ (0xff << 16)) | (sam.RegValue(val) << 16)
|
||||
case 63: // PB31
|
||||
sam.PORT.PINCFG1_28 = (sam.PORT.PINCFG1_28 &^ (0xff << 24)) | (sam.RegValue(val) << 24)
|
||||
}
|
||||
}
|
|
@ -293,59 +293,6 @@ func handleRTC() {
|
|||
timerWakeup = true
|
||||
}
|
||||
|
||||
func initSERCOMClocks() {
|
||||
// Turn on clock to SERCOM0 for UART0
|
||||
sam.PM.APBCMASK |= sam.PM_APBCMASK_SERCOM0_
|
||||
|
||||
// Use GCLK0 for SERCOM0 aka UART0
|
||||
// GCLK_CLKCTRL_ID( clockId ) | // Generic Clock 0 (SERCOMx)
|
||||
// GCLK_CLKCTRL_GEN_GCLK0 | // Generic Clock Generator 0 is source
|
||||
// GCLK_CLKCTRL_CLKEN ;
|
||||
sam.GCLK.CLKCTRL = sam.RegValue16((sam.GCLK_CLKCTRL_ID_SERCOM0_CORE << sam.GCLK_CLKCTRL_ID_Pos) |
|
||||
(sam.GCLK_CLKCTRL_GEN_GCLK0 << sam.GCLK_CLKCTRL_GEN_Pos) |
|
||||
sam.GCLK_CLKCTRL_CLKEN)
|
||||
waitForSync()
|
||||
|
||||
// Turn on clock to SERCOM1
|
||||
sam.PM.APBCMASK |= sam.PM_APBCMASK_SERCOM1_
|
||||
sam.GCLK.CLKCTRL = sam.RegValue16((sam.GCLK_CLKCTRL_ID_SERCOM1_CORE << sam.GCLK_CLKCTRL_ID_Pos) |
|
||||
(sam.GCLK_CLKCTRL_GEN_GCLK0 << sam.GCLK_CLKCTRL_GEN_Pos) |
|
||||
sam.GCLK_CLKCTRL_CLKEN)
|
||||
waitForSync()
|
||||
|
||||
// Turn on clock to SERCOM2
|
||||
sam.PM.APBCMASK |= sam.PM_APBCMASK_SERCOM2_
|
||||
sam.GCLK.CLKCTRL = sam.RegValue16((sam.GCLK_CLKCTRL_ID_SERCOM2_CORE << sam.GCLK_CLKCTRL_ID_Pos) |
|
||||
(sam.GCLK_CLKCTRL_GEN_GCLK0 << sam.GCLK_CLKCTRL_GEN_Pos) |
|
||||
sam.GCLK_CLKCTRL_CLKEN)
|
||||
waitForSync()
|
||||
|
||||
// Turn on clock to SERCOM3
|
||||
sam.PM.APBCMASK |= sam.PM_APBCMASK_SERCOM3_
|
||||
sam.GCLK.CLKCTRL = sam.RegValue16((sam.GCLK_CLKCTRL_ID_SERCOM3_CORE << sam.GCLK_CLKCTRL_ID_Pos) |
|
||||
(sam.GCLK_CLKCTRL_GEN_GCLK0 << sam.GCLK_CLKCTRL_GEN_Pos) |
|
||||
sam.GCLK_CLKCTRL_CLKEN)
|
||||
waitForSync()
|
||||
|
||||
// Turn on clock to SERCOM4
|
||||
sam.PM.APBCMASK |= sam.PM_APBCMASK_SERCOM4_
|
||||
|
||||
// Use GCLK0 for SERCOM4
|
||||
sam.GCLK.CLKCTRL = sam.RegValue16((sam.GCLK_CLKCTRL_ID_SERCOM4_CORE << sam.GCLK_CLKCTRL_ID_Pos) |
|
||||
(sam.GCLK_CLKCTRL_GEN_GCLK0 << sam.GCLK_CLKCTRL_GEN_Pos) |
|
||||
sam.GCLK_CLKCTRL_CLKEN)
|
||||
waitForSync()
|
||||
|
||||
// Turn on clock to SERCOM5
|
||||
sam.PM.APBCMASK |= sam.PM_APBCMASK_SERCOM5_
|
||||
|
||||
// Use GCLK0 for SERCOM5
|
||||
sam.GCLK.CLKCTRL = sam.RegValue16((sam.GCLK_CLKCTRL_ID_SERCOM5_CORE << sam.GCLK_CLKCTRL_ID_Pos) |
|
||||
(sam.GCLK_CLKCTRL_GEN_GCLK0 << sam.GCLK_CLKCTRL_GEN_Pos) |
|
||||
sam.GCLK_CLKCTRL_CLKEN)
|
||||
waitForSync()
|
||||
}
|
||||
|
||||
func initUSBClock() {
|
||||
// Turn on clock for USB
|
||||
sam.PM.APBBMASK |= sam.PM_APBBMASK_USB_
|
||||
|
|
42
src/runtime/runtime_atsamd21e18.go
Обычный файл
42
src/runtime/runtime_atsamd21e18.go
Обычный файл
|
@ -0,0 +1,42 @@
|
|||
// +build sam,atsamd21,atsamd21e18
|
||||
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"device/sam"
|
||||
)
|
||||
|
||||
func initSERCOMClocks() {
|
||||
// Turn on clock to SERCOM0 for UART0
|
||||
sam.PM.APBCMASK |= sam.PM_APBCMASK_SERCOM0_
|
||||
|
||||
// Use GCLK0 for SERCOM0 aka UART0
|
||||
// GCLK_CLKCTRL_ID( clockId ) | // Generic Clock 0 (SERCOMx)
|
||||
// GCLK_CLKCTRL_GEN_GCLK0 | // Generic Clock Generator 0 is source
|
||||
// GCLK_CLKCTRL_CLKEN ;
|
||||
sam.GCLK.CLKCTRL = sam.RegValue16((sam.GCLK_CLKCTRL_ID_SERCOM0_CORE << sam.GCLK_CLKCTRL_ID_Pos) |
|
||||
(sam.GCLK_CLKCTRL_GEN_GCLK0 << sam.GCLK_CLKCTRL_GEN_Pos) |
|
||||
sam.GCLK_CLKCTRL_CLKEN)
|
||||
waitForSync()
|
||||
|
||||
// Turn on clock to SERCOM1
|
||||
sam.PM.APBCMASK |= sam.PM_APBCMASK_SERCOM1_
|
||||
sam.GCLK.CLKCTRL = sam.RegValue16((sam.GCLK_CLKCTRL_ID_SERCOM1_CORE << sam.GCLK_CLKCTRL_ID_Pos) |
|
||||
(sam.GCLK_CLKCTRL_GEN_GCLK0 << sam.GCLK_CLKCTRL_GEN_Pos) |
|
||||
sam.GCLK_CLKCTRL_CLKEN)
|
||||
waitForSync()
|
||||
|
||||
// Turn on clock to SERCOM2
|
||||
sam.PM.APBCMASK |= sam.PM_APBCMASK_SERCOM2_
|
||||
sam.GCLK.CLKCTRL = sam.RegValue16((sam.GCLK_CLKCTRL_ID_SERCOM2_CORE << sam.GCLK_CLKCTRL_ID_Pos) |
|
||||
(sam.GCLK_CLKCTRL_GEN_GCLK0 << sam.GCLK_CLKCTRL_GEN_Pos) |
|
||||
sam.GCLK_CLKCTRL_CLKEN)
|
||||
waitForSync()
|
||||
|
||||
// Turn on clock to SERCOM3
|
||||
sam.PM.APBCMASK |= sam.PM_APBCMASK_SERCOM3_
|
||||
sam.GCLK.CLKCTRL = sam.RegValue16((sam.GCLK_CLKCTRL_ID_SERCOM3_CORE << sam.GCLK_CLKCTRL_ID_Pos) |
|
||||
(sam.GCLK_CLKCTRL_GEN_GCLK0 << sam.GCLK_CLKCTRL_GEN_Pos) |
|
||||
sam.GCLK_CLKCTRL_CLKEN)
|
||||
waitForSync()
|
||||
}
|
60
src/runtime/runtime_atsamd21g18.go
Обычный файл
60
src/runtime/runtime_atsamd21g18.go
Обычный файл
|
@ -0,0 +1,60 @@
|
|||
// +build sam,atsamd21,atsamd21g18
|
||||
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"device/sam"
|
||||
)
|
||||
|
||||
func initSERCOMClocks() {
|
||||
// Turn on clock to SERCOM0 for UART0
|
||||
sam.PM.APBCMASK |= sam.PM_APBCMASK_SERCOM0_
|
||||
|
||||
// Use GCLK0 for SERCOM0 aka UART0
|
||||
// GCLK_CLKCTRL_ID( clockId ) | // Generic Clock 0 (SERCOMx)
|
||||
// GCLK_CLKCTRL_GEN_GCLK0 | // Generic Clock Generator 0 is source
|
||||
// GCLK_CLKCTRL_CLKEN ;
|
||||
sam.GCLK.CLKCTRL = sam.RegValue16((sam.GCLK_CLKCTRL_ID_SERCOM0_CORE << sam.GCLK_CLKCTRL_ID_Pos) |
|
||||
(sam.GCLK_CLKCTRL_GEN_GCLK0 << sam.GCLK_CLKCTRL_GEN_Pos) |
|
||||
sam.GCLK_CLKCTRL_CLKEN)
|
||||
waitForSync()
|
||||
|
||||
// Turn on clock to SERCOM1
|
||||
sam.PM.APBCMASK |= sam.PM_APBCMASK_SERCOM1_
|
||||
sam.GCLK.CLKCTRL = sam.RegValue16((sam.GCLK_CLKCTRL_ID_SERCOM1_CORE << sam.GCLK_CLKCTRL_ID_Pos) |
|
||||
(sam.GCLK_CLKCTRL_GEN_GCLK0 << sam.GCLK_CLKCTRL_GEN_Pos) |
|
||||
sam.GCLK_CLKCTRL_CLKEN)
|
||||
waitForSync()
|
||||
|
||||
// Turn on clock to SERCOM2
|
||||
sam.PM.APBCMASK |= sam.PM_APBCMASK_SERCOM2_
|
||||
sam.GCLK.CLKCTRL = sam.RegValue16((sam.GCLK_CLKCTRL_ID_SERCOM2_CORE << sam.GCLK_CLKCTRL_ID_Pos) |
|
||||
(sam.GCLK_CLKCTRL_GEN_GCLK0 << sam.GCLK_CLKCTRL_GEN_Pos) |
|
||||
sam.GCLK_CLKCTRL_CLKEN)
|
||||
waitForSync()
|
||||
|
||||
// Turn on clock to SERCOM3
|
||||
sam.PM.APBCMASK |= sam.PM_APBCMASK_SERCOM3_
|
||||
sam.GCLK.CLKCTRL = sam.RegValue16((sam.GCLK_CLKCTRL_ID_SERCOM3_CORE << sam.GCLK_CLKCTRL_ID_Pos) |
|
||||
(sam.GCLK_CLKCTRL_GEN_GCLK0 << sam.GCLK_CLKCTRL_GEN_Pos) |
|
||||
sam.GCLK_CLKCTRL_CLKEN)
|
||||
waitForSync()
|
||||
|
||||
// Turn on clock to SERCOM4
|
||||
sam.PM.APBCMASK |= sam.PM_APBCMASK_SERCOM4_
|
||||
|
||||
// Use GCLK0 for SERCOM4
|
||||
sam.GCLK.CLKCTRL = sam.RegValue16((sam.GCLK_CLKCTRL_ID_SERCOM4_CORE << sam.GCLK_CLKCTRL_ID_Pos) |
|
||||
(sam.GCLK_CLKCTRL_GEN_GCLK0 << sam.GCLK_CLKCTRL_GEN_Pos) |
|
||||
sam.GCLK_CLKCTRL_CLKEN)
|
||||
waitForSync()
|
||||
|
||||
// Turn on clock to SERCOM5
|
||||
sam.PM.APBCMASK |= sam.PM_APBCMASK_SERCOM5_
|
||||
|
||||
// Use GCLK0 for SERCOM5
|
||||
sam.GCLK.CLKCTRL = sam.RegValue16((sam.GCLK_CLKCTRL_ID_SERCOM5_CORE << sam.GCLK_CLKCTRL_ID_Pos) |
|
||||
(sam.GCLK_CLKCTRL_GEN_GCLK0 << sam.GCLK_CLKCTRL_GEN_Pos) |
|
||||
sam.GCLK_CLKCTRL_CLKEN)
|
||||
waitForSync()
|
||||
}
|
15
targets/atsamd21e18a.json
Обычный файл
15
targets/atsamd21e18a.json
Обычный файл
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"inherits": ["cortex-m"],
|
||||
"llvm-target": "armv6m-none-eabi",
|
||||
"build-tags": ["atsamd21e18", "atsamd21", "sam"],
|
||||
"cflags": [
|
||||
"--target=armv6m-none-eabi",
|
||||
"-Qunused-arguments"
|
||||
],
|
||||
"ldflags": [
|
||||
"-T", "targets/atsamd21.ld"
|
||||
],
|
||||
"extra-files": [
|
||||
"src/device/sam/atsamd21e18a.s"
|
||||
]
|
||||
}
|
5
targets/trinket-m0.json
Обычный файл
5
targets/trinket-m0.json
Обычный файл
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"inherits": ["atsamd21e18a"],
|
||||
"build-tags": ["sam", "atsamd21e18a", "trinket_m0"],
|
||||
"flash": "bossac -d -i -e -w -v -R --offset=0x2000 {hex}"
|
||||
}
|
Загрузка…
Создание таблицы
Сослаться в новой задаче