machine/atsamd51: add support for ATSAMD51 processor using Adafruit ItsyBitsy-M4 board
Signed-off-by: Ron Evans <ron@hybridgroup.com>
Этот коммит содержится в:
родитель
bc41cc688f
коммит
02c4020228
9 изменённых файлов: 3054 добавлений и 0 удалений
1
Makefile
1
Makefile
|
@ -125,6 +125,7 @@ smoketest:
|
||||||
tinygo build -size short -o test.elf -target=stm32f4disco examples/blinky2
|
tinygo build -size short -o test.elf -target=stm32f4disco examples/blinky2
|
||||||
tinygo build -size short -o test.elf -target=circuitplay-express examples/i2s
|
tinygo build -size short -o test.elf -target=circuitplay-express examples/i2s
|
||||||
tinygo build -size short -o test.elf -target=gameboy-advance examples/gba-display
|
tinygo build -size short -o test.elf -target=gameboy-advance examples/gba-display
|
||||||
|
tinygo build -size short -o test.elf -target=itsybitsy-m4 examples/blinky1
|
||||||
ifneq ($(AVR), 0)
|
ifneq ($(AVR), 0)
|
||||||
tinygo build -size short -o test.elf -target=arduino examples/blinky1
|
tinygo build -size short -o test.elf -target=arduino examples/blinky1
|
||||||
tinygo build -size short -o test.elf -target=digispark examples/blinky1
|
tinygo build -size short -o test.elf -target=digispark examples/blinky1
|
||||||
|
|
83
src/machine/board_itsybitsy-m4.go
Обычный файл
83
src/machine/board_itsybitsy-m4.go
Обычный файл
|
@ -0,0 +1,83 @@
|
||||||
|
// +build sam,atsamd51,itsybitsy_m4
|
||||||
|
|
||||||
|
package machine
|
||||||
|
|
||||||
|
import "device/sam"
|
||||||
|
|
||||||
|
// used to reset into bootloader
|
||||||
|
const RESET_MAGIC_VALUE = 0xf01669ef
|
||||||
|
|
||||||
|
// GPIO Pins
|
||||||
|
const (
|
||||||
|
D0 = PA16 // UART0 RX/PWM available
|
||||||
|
D1 = PA17 // UART0 TX/PWM available
|
||||||
|
D2 = PA07
|
||||||
|
D3 = PB22
|
||||||
|
D4 = PA14 // PWM available
|
||||||
|
D5 = PA15 // PWM available
|
||||||
|
D6 = PB02 // dotStar clock
|
||||||
|
D7 = PA18 // PWM available
|
||||||
|
D8 = PB03 // dotStar data
|
||||||
|
D9 = PA19 // PWM available
|
||||||
|
D10 = PA20 // can be used for PWM or UART1 TX
|
||||||
|
D11 = PA21 // can be used for PWM or UART1 RX
|
||||||
|
D12 = PA23 // PWM available
|
||||||
|
D13 = PA22 // PWM available
|
||||||
|
)
|
||||||
|
|
||||||
|
// Analog pins
|
||||||
|
const (
|
||||||
|
A0 = PA02 // ADC/AIN[0]
|
||||||
|
A1 = PB05 // ADC/AIN[2]
|
||||||
|
A2 = PB08 // ADC/AIN[3]
|
||||||
|
A3 = PB09 // ADC/AIN[4]
|
||||||
|
A4 = PA04 // ADC/AIN[5]
|
||||||
|
A5 = PA06 // ADC/AIN[10]
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
LED = D13
|
||||||
|
)
|
||||||
|
|
||||||
|
// UART0 aka USBCDC pins
|
||||||
|
const (
|
||||||
|
USBCDC_DM_PIN = PA24
|
||||||
|
USBCDC_DP_PIN = PA25
|
||||||
|
)
|
||||||
|
|
||||||
|
// UART1 pins
|
||||||
|
const (
|
||||||
|
UART_TX_PIN = D1
|
||||||
|
UART_RX_PIN = D0
|
||||||
|
)
|
||||||
|
|
||||||
|
// I2C pins
|
||||||
|
const (
|
||||||
|
SDA_PIN = PA12 // SDA: SERCOM3/PAD[0]
|
||||||
|
SCL_PIN = PA13 // SCL: SERCOM3/PAD[1]
|
||||||
|
)
|
||||||
|
|
||||||
|
// I2C on the ItsyBitsy M4.
|
||||||
|
var (
|
||||||
|
I2C0 = I2C{Bus: sam.SERCOM2_I2CM,
|
||||||
|
SDA: SDA_PIN,
|
||||||
|
SCL: SCL_PIN,
|
||||||
|
PinMode: PinSERCOM}
|
||||||
|
)
|
||||||
|
|
||||||
|
// SPI pins
|
||||||
|
const (
|
||||||
|
SPI0_SCK_PIN = PA01 // SCK: SERCOM1/PAD[1]
|
||||||
|
SPI0_MOSI_PIN = PA00 // MOSI: SERCOM1/PAD[0]
|
||||||
|
SPI0_MISO_PIN = PB23 // MISO: SERCOM1/PAD[3]
|
||||||
|
)
|
||||||
|
|
||||||
|
// SPI on the ItsyBitsy M4.
|
||||||
|
var (
|
||||||
|
SPI0 = SPI{Bus: sam.SERCOM1_SPI,
|
||||||
|
SCK: SPI0_SCK_PIN,
|
||||||
|
MOSI: SPI0_MOSI_PIN,
|
||||||
|
MISO: SPI0_MISO_PIN,
|
||||||
|
DOpad: spiTXPad2SCK3,
|
||||||
|
DIpad: sercomRXPad0}
|
||||||
|
)
|
2026
src/machine/machine_atsamd51.go
Обычный файл
2026
src/machine/machine_atsamd51.go
Обычный файл
Различия файлов не показаны, т.к. их слишком много
Показать различия
569
src/machine/machine_atsamd51g19.go
Обычный файл
569
src/machine/machine_atsamd51g19.go
Обычный файл
|
@ -0,0 +1,569 @@
|
||||||
|
// +build sam,atsamd51,atsamd51g19
|
||||||
|
|
||||||
|
// Peripheral abstraction layer for the atsamd51.
|
||||||
|
//
|
||||||
|
// Datasheet:
|
||||||
|
// http://ww1.microchip.com/downloads/en/DeviceDoc/60001507C.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 Pin) PortMaskSet() (*uint32, uint32) {
|
||||||
|
if p < 32 {
|
||||||
|
return &sam.PORT.OUTSET0.Reg, 1 << uint8(p)
|
||||||
|
} else {
|
||||||
|
return &sam.PORT.OUTSET1.Reg, 1 << uint8(p-32)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the register and mask to disable a given port. This can be used to
|
||||||
|
// implement bit-banged drivers.
|
||||||
|
func (p Pin) PortMaskClear() (*uint32, uint32) {
|
||||||
|
if p < 32 {
|
||||||
|
return &sam.PORT.OUTCLR0.Reg, 1 << uint8(p)
|
||||||
|
} else {
|
||||||
|
return &sam.PORT.OUTCLR1.Reg, 1 << uint8(p-32)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the pin to high or low.
|
||||||
|
// Warning: only use this on an output pin!
|
||||||
|
func (p Pin) Set(high bool) {
|
||||||
|
if p < 32 {
|
||||||
|
if high {
|
||||||
|
sam.PORT.OUTSET0.Set(1 << uint8(p))
|
||||||
|
} else {
|
||||||
|
sam.PORT.OUTCLR0.Set(1 << uint8(p))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if high {
|
||||||
|
sam.PORT.OUTSET1.Set(1 << uint8(p-32))
|
||||||
|
} else {
|
||||||
|
sam.PORT.OUTCLR1.Set(1 << uint8(p-32))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get returns the current value of a GPIO pin.
|
||||||
|
func (p Pin) Get() bool {
|
||||||
|
if p < 32 {
|
||||||
|
return (sam.PORT.IN0.Get()>>uint8(p))&1 > 0
|
||||||
|
} else {
|
||||||
|
return (sam.PORT.IN1.Get()>>(uint8(p)-32))&1 > 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure this pin with the given configuration.
|
||||||
|
func (p Pin) Configure(config PinConfig) {
|
||||||
|
switch config.Mode {
|
||||||
|
case PinOutput:
|
||||||
|
if p < 32 {
|
||||||
|
sam.PORT.DIRSET0.Set(1 << uint8(p))
|
||||||
|
// 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.Set(1 << uint8(p-32))
|
||||||
|
// output is also set to input enable so pin can read back its own value
|
||||||
|
p.setPinCfg(sam.PORT_PINCFG0_INEN)
|
||||||
|
}
|
||||||
|
|
||||||
|
case PinInput:
|
||||||
|
if p < 32 {
|
||||||
|
sam.PORT.DIRCLR0.Set(1 << uint8(p))
|
||||||
|
p.setPinCfg(sam.PORT_PINCFG0_INEN)
|
||||||
|
} else {
|
||||||
|
sam.PORT.DIRCLR1.Set(1<<uint8(p) - 32)
|
||||||
|
p.setPinCfg(sam.PORT_PINCFG0_INEN)
|
||||||
|
}
|
||||||
|
|
||||||
|
case PinInputPulldown:
|
||||||
|
if p < 32 {
|
||||||
|
sam.PORT.DIRCLR0.Set(1 << uint8(p))
|
||||||
|
sam.PORT.OUTCLR0.Set(1 << uint8(p))
|
||||||
|
p.setPinCfg(sam.PORT_PINCFG0_INEN | sam.PORT_PINCFG0_PULLEN)
|
||||||
|
} else {
|
||||||
|
sam.PORT.DIRCLR1.Set(1<<uint8(p) - 32)
|
||||||
|
sam.PORT.OUTCLR1.Set(1<<uint8(p) - 32)
|
||||||
|
p.setPinCfg(sam.PORT_PINCFG0_INEN | sam.PORT_PINCFG0_PULLEN)
|
||||||
|
}
|
||||||
|
|
||||||
|
case PinInputPullup:
|
||||||
|
if p < 32 {
|
||||||
|
sam.PORT.DIRCLR0.Set(1 << uint8(p))
|
||||||
|
sam.PORT.OUTSET0.Set(1 << uint8(p))
|
||||||
|
p.setPinCfg(sam.PORT_PINCFG0_INEN | sam.PORT_PINCFG0_PULLEN)
|
||||||
|
} else {
|
||||||
|
sam.PORT.DIRCLR1.Set(1<<uint8(p) - 32)
|
||||||
|
sam.PORT.OUTSET1.Set(1<<uint8(p) - 32)
|
||||||
|
p.setPinCfg(sam.PORT_PINCFG0_INEN | sam.PORT_PINCFG0_PULLEN)
|
||||||
|
}
|
||||||
|
|
||||||
|
case PinSERCOM:
|
||||||
|
if p&1 > 0 {
|
||||||
|
// odd pin, so save the even pins
|
||||||
|
val := p.getPMux() & sam.PORT_PMUX0_PMUXE_Msk
|
||||||
|
p.setPMux(val | (uint8(PinSERCOM) << sam.PORT_PMUX0_PMUXO_Pos))
|
||||||
|
} else {
|
||||||
|
// even pin, so save the odd pins
|
||||||
|
val := p.getPMux() & sam.PORT_PMUX0_PMUXO_Msk
|
||||||
|
p.setPMux(val | (uint8(PinSERCOM) << sam.PORT_PMUX0_PMUXE_Pos))
|
||||||
|
}
|
||||||
|
// enable port config
|
||||||
|
p.setPinCfg(sam.PORT_PINCFG0_PMUXEN | sam.PORT_PINCFG0_DRVSTR | sam.PORT_PINCFG0_INEN)
|
||||||
|
|
||||||
|
case PinSERCOMAlt:
|
||||||
|
if p&1 > 0 {
|
||||||
|
// odd pin, so save the even pins
|
||||||
|
val := p.getPMux() & sam.PORT_PMUX0_PMUXE_Msk
|
||||||
|
p.setPMux(val | (uint8(PinSERCOMAlt) << sam.PORT_PMUX0_PMUXO_Pos))
|
||||||
|
} else {
|
||||||
|
// even pin, so save the odd pins
|
||||||
|
val := p.getPMux() & sam.PORT_PMUX0_PMUXO_Msk
|
||||||
|
p.setPMux(val | (uint8(PinSERCOMAlt) << sam.PORT_PMUX0_PMUXE_Pos))
|
||||||
|
}
|
||||||
|
// enable port config
|
||||||
|
p.setPinCfg(sam.PORT_PINCFG0_PMUXEN | sam.PORT_PINCFG0_DRVSTR)
|
||||||
|
|
||||||
|
case PinCom:
|
||||||
|
if p&1 > 0 {
|
||||||
|
// odd pin, so save the even pins
|
||||||
|
val := p.getPMux() & sam.PORT_PMUX0_PMUXE_Msk
|
||||||
|
p.setPMux(val | (uint8(PinCom) << sam.PORT_PMUX0_PMUXO_Pos))
|
||||||
|
} else {
|
||||||
|
// even pin, so save the odd pins
|
||||||
|
val := p.getPMux() & sam.PORT_PMUX0_PMUXO_Msk
|
||||||
|
p.setPMux(val | (uint8(PinCom) << sam.PORT_PMUX0_PMUXE_Pos))
|
||||||
|
}
|
||||||
|
// enable port config
|
||||||
|
p.setPinCfg(sam.PORT_PINCFG0_PMUXEN)
|
||||||
|
case PinAnalog:
|
||||||
|
if p&1 > 0 {
|
||||||
|
// odd pin, so save the even pins
|
||||||
|
val := p.getPMux() & sam.PORT_PMUX0_PMUXE_Msk
|
||||||
|
p.setPMux(val | (uint8(PinAnalog) << sam.PORT_PMUX0_PMUXO_Pos))
|
||||||
|
} else {
|
||||||
|
// even pin, so save the odd pins
|
||||||
|
val := p.getPMux() & sam.PORT_PMUX0_PMUXO_Msk
|
||||||
|
p.setPMux(val | (uint8(PinAnalog) << 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 (p Pin) getPMux() uint8 {
|
||||||
|
switch uint8(p) >> 1 {
|
||||||
|
case 0:
|
||||||
|
return sam.PORT.PMUX0_0.Get()
|
||||||
|
case 1:
|
||||||
|
return sam.PORT.PMUX0_1.Get()
|
||||||
|
case 2:
|
||||||
|
return sam.PORT.PMUX0_2.Get()
|
||||||
|
case 3:
|
||||||
|
return sam.PORT.PMUX0_3.Get()
|
||||||
|
case 4:
|
||||||
|
return sam.PORT.PMUX0_4.Get()
|
||||||
|
case 5:
|
||||||
|
return sam.PORT.PMUX0_5.Get()
|
||||||
|
case 6:
|
||||||
|
return sam.PORT.PMUX0_6.Get()
|
||||||
|
case 7:
|
||||||
|
return sam.PORT.PMUX0_7.Get()
|
||||||
|
case 8:
|
||||||
|
return sam.PORT.PMUX0_8.Get()
|
||||||
|
case 9:
|
||||||
|
return sam.PORT.PMUX0_9.Get()
|
||||||
|
case 10:
|
||||||
|
return sam.PORT.PMUX0_10.Get()
|
||||||
|
case 11:
|
||||||
|
return sam.PORT.PMUX0_11.Get()
|
||||||
|
case 12:
|
||||||
|
return sam.PORT.PMUX0_12.Get()
|
||||||
|
case 13:
|
||||||
|
return sam.PORT.PMUX0_13.Get()
|
||||||
|
case 14:
|
||||||
|
return sam.PORT.PMUX0_14.Get()
|
||||||
|
case 15:
|
||||||
|
return sam.PORT.PMUX0_15.Get()
|
||||||
|
case 16:
|
||||||
|
return uint8(sam.PORT.PMUX1_0.Get()>>0) & 0xff
|
||||||
|
case 17:
|
||||||
|
return uint8(sam.PORT.PMUX1_0.Get()>>8) & 0xff
|
||||||
|
case 18:
|
||||||
|
return uint8(sam.PORT.PMUX1_0.Get()>>16) & 0xff
|
||||||
|
case 19:
|
||||||
|
return uint8(sam.PORT.PMUX1_0.Get()>>24) & 0xff
|
||||||
|
case 20:
|
||||||
|
return uint8(sam.PORT.PMUX1_4.Get()>>0) & 0xff
|
||||||
|
case 21:
|
||||||
|
return uint8(sam.PORT.PMUX1_4.Get()>>8) & 0xff
|
||||||
|
case 22:
|
||||||
|
return uint8(sam.PORT.PMUX1_4.Get()>>16) & 0xff
|
||||||
|
case 23:
|
||||||
|
return uint8(sam.PORT.PMUX1_4.Get()>>24) & 0xff
|
||||||
|
case 24:
|
||||||
|
return uint8(sam.PORT.PMUX1_8.Get()>>0) & 0xff
|
||||||
|
case 25:
|
||||||
|
return uint8(sam.PORT.PMUX1_8.Get()>>8) & 0xff
|
||||||
|
case 26:
|
||||||
|
return uint8(sam.PORT.PMUX1_8.Get()>>16) & 0xff
|
||||||
|
case 27:
|
||||||
|
return uint8(sam.PORT.PMUX1_8.Get()>>24) & 0xff
|
||||||
|
case 28:
|
||||||
|
return uint8(sam.PORT.PMUX1_12.Get()>>0) & 0xff
|
||||||
|
case 29:
|
||||||
|
return uint8(sam.PORT.PMUX1_12.Get()>>8) & 0xff
|
||||||
|
case 30:
|
||||||
|
return uint8(sam.PORT.PMUX1_12.Get()>>16) & 0xff
|
||||||
|
case 31:
|
||||||
|
return uint8(sam.PORT.PMUX1_12.Get()>>24) & 0xff
|
||||||
|
default:
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// setPMux sets the value for the correct PMUX register for this pin.
|
||||||
|
func (p Pin) setPMux(val uint8) {
|
||||||
|
switch uint8(p) >> 1 {
|
||||||
|
case 0:
|
||||||
|
sam.PORT.PMUX0_0.Set(val)
|
||||||
|
case 1:
|
||||||
|
sam.PORT.PMUX0_1.Set(val)
|
||||||
|
case 2:
|
||||||
|
sam.PORT.PMUX0_2.Set(val)
|
||||||
|
case 3:
|
||||||
|
sam.PORT.PMUX0_3.Set(val)
|
||||||
|
case 4:
|
||||||
|
sam.PORT.PMUX0_4.Set(val)
|
||||||
|
case 5:
|
||||||
|
sam.PORT.PMUX0_5.Set(val)
|
||||||
|
case 6:
|
||||||
|
sam.PORT.PMUX0_6.Set(val)
|
||||||
|
case 7:
|
||||||
|
sam.PORT.PMUX0_7.Set(val)
|
||||||
|
case 8:
|
||||||
|
sam.PORT.PMUX0_8.Set(val)
|
||||||
|
case 9:
|
||||||
|
sam.PORT.PMUX0_9.Set(val)
|
||||||
|
case 10:
|
||||||
|
sam.PORT.PMUX0_10.Set(val)
|
||||||
|
case 11:
|
||||||
|
sam.PORT.PMUX0_11.Set(val)
|
||||||
|
case 12:
|
||||||
|
sam.PORT.PMUX0_12.Set(val)
|
||||||
|
case 13:
|
||||||
|
sam.PORT.PMUX0_13.Set(val)
|
||||||
|
case 14:
|
||||||
|
sam.PORT.PMUX0_14.Set(val)
|
||||||
|
case 15:
|
||||||
|
sam.PORT.PMUX0_15.Set(val)
|
||||||
|
case 16:
|
||||||
|
sam.PORT.PMUX1_0.Set(sam.PORT.PMUX1_0.Get()&^(0xff<<0) | (uint32(val) << 0))
|
||||||
|
case 17:
|
||||||
|
sam.PORT.PMUX1_0.Set(sam.PORT.PMUX1_0.Get()&^(0xff<<8) | (uint32(val) << 8))
|
||||||
|
case 18:
|
||||||
|
sam.PORT.PMUX1_0.Set(sam.PORT.PMUX1_0.Get()&^(0xff<<16) | (uint32(val) << 16))
|
||||||
|
case 19:
|
||||||
|
sam.PORT.PMUX1_0.Set(sam.PORT.PMUX1_0.Get()&^(0xff<<24) | (uint32(val) << 24))
|
||||||
|
case 20:
|
||||||
|
sam.PORT.PMUX1_4.Set(sam.PORT.PMUX1_4.Get()&^(0xff<<0) | (uint32(val) << 0))
|
||||||
|
case 21:
|
||||||
|
sam.PORT.PMUX1_4.Set(sam.PORT.PMUX1_4.Get()&^(0xff<<8) | (uint32(val) << 8))
|
||||||
|
case 22:
|
||||||
|
sam.PORT.PMUX1_4.Set(sam.PORT.PMUX1_4.Get()&^(0xff<<16) | (uint32(val) << 16))
|
||||||
|
case 23:
|
||||||
|
sam.PORT.PMUX1_4.Set(sam.PORT.PMUX1_4.Get()&^(0xff<<24) | (uint32(val) << 24))
|
||||||
|
case 24:
|
||||||
|
sam.PORT.PMUX1_8.Set(sam.PORT.PMUX1_8.Get()&^(0xff<<0) | (uint32(val) << 0))
|
||||||
|
case 25:
|
||||||
|
sam.PORT.PMUX1_8.Set(sam.PORT.PMUX1_8.Get()&^(0xff<<8) | (uint32(val) << 8))
|
||||||
|
case 26:
|
||||||
|
sam.PORT.PMUX1_8.Set(sam.PORT.PMUX1_8.Get()&^(0xff<<16) | (uint32(val) << 16))
|
||||||
|
case 27:
|
||||||
|
sam.PORT.PMUX1_8.Set(sam.PORT.PMUX1_8.Get()&^(0xff<<24) | (uint32(val) << 24))
|
||||||
|
case 28:
|
||||||
|
sam.PORT.PMUX1_12.Set(sam.PORT.PMUX1_12.Get()&^(0xff<<0) | (uint32(val) << 0))
|
||||||
|
case 29:
|
||||||
|
sam.PORT.PMUX1_12.Set(sam.PORT.PMUX1_12.Get()&^(0xff<<8) | (uint32(val) << 8))
|
||||||
|
case 30:
|
||||||
|
sam.PORT.PMUX1_12.Set(sam.PORT.PMUX1_12.Get()&^(0xff<<16) | (uint32(val) << 16))
|
||||||
|
case 31:
|
||||||
|
sam.PORT.PMUX1_12.Set(sam.PORT.PMUX1_12.Get()&^(0xff<<24) | (uint32(val) << 24))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// getPinCfg returns the value for the correct PINCFG register for this pin.
|
||||||
|
func (p Pin) getPinCfg() uint8 {
|
||||||
|
switch p {
|
||||||
|
case 0:
|
||||||
|
return sam.PORT.PINCFG0_0.Get()
|
||||||
|
case 1:
|
||||||
|
return sam.PORT.PINCFG0_1.Get()
|
||||||
|
case 2:
|
||||||
|
return sam.PORT.PINCFG0_2.Get()
|
||||||
|
case 3:
|
||||||
|
return sam.PORT.PINCFG0_3.Get()
|
||||||
|
case 4:
|
||||||
|
return sam.PORT.PINCFG0_4.Get()
|
||||||
|
case 5:
|
||||||
|
return sam.PORT.PINCFG0_5.Get()
|
||||||
|
case 6:
|
||||||
|
return sam.PORT.PINCFG0_6.Get()
|
||||||
|
case 7:
|
||||||
|
return sam.PORT.PINCFG0_7.Get()
|
||||||
|
case 8:
|
||||||
|
return sam.PORT.PINCFG0_8.Get()
|
||||||
|
case 9:
|
||||||
|
return sam.PORT.PINCFG0_9.Get()
|
||||||
|
case 10:
|
||||||
|
return sam.PORT.PINCFG0_10.Get()
|
||||||
|
case 11:
|
||||||
|
return sam.PORT.PINCFG0_11.Get()
|
||||||
|
case 12:
|
||||||
|
return sam.PORT.PINCFG0_12.Get()
|
||||||
|
case 13:
|
||||||
|
return sam.PORT.PINCFG0_13.Get()
|
||||||
|
case 14:
|
||||||
|
return sam.PORT.PINCFG0_14.Get()
|
||||||
|
case 15:
|
||||||
|
return sam.PORT.PINCFG0_15.Get()
|
||||||
|
case 16:
|
||||||
|
return sam.PORT.PINCFG0_16.Get()
|
||||||
|
case 17:
|
||||||
|
return sam.PORT.PINCFG0_17.Get()
|
||||||
|
case 18:
|
||||||
|
return sam.PORT.PINCFG0_18.Get()
|
||||||
|
case 19:
|
||||||
|
return sam.PORT.PINCFG0_19.Get()
|
||||||
|
case 20:
|
||||||
|
return sam.PORT.PINCFG0_20.Get()
|
||||||
|
case 21:
|
||||||
|
return sam.PORT.PINCFG0_21.Get()
|
||||||
|
case 22:
|
||||||
|
return sam.PORT.PINCFG0_22.Get()
|
||||||
|
case 23:
|
||||||
|
return sam.PORT.PINCFG0_23.Get()
|
||||||
|
case 24:
|
||||||
|
return sam.PORT.PINCFG0_24.Get()
|
||||||
|
case 25:
|
||||||
|
return sam.PORT.PINCFG0_25.Get()
|
||||||
|
case 26:
|
||||||
|
return sam.PORT.PINCFG0_26.Get()
|
||||||
|
case 27:
|
||||||
|
return sam.PORT.PINCFG0_27.Get()
|
||||||
|
case 28:
|
||||||
|
return sam.PORT.PINCFG0_28.Get()
|
||||||
|
case 29:
|
||||||
|
return sam.PORT.PINCFG0_29.Get()
|
||||||
|
case 30:
|
||||||
|
return sam.PORT.PINCFG0_30.Get()
|
||||||
|
case 31:
|
||||||
|
return sam.PORT.PINCFG0_31.Get()
|
||||||
|
case 32: // PB00
|
||||||
|
return uint8(sam.PORT.PINCFG1_0.Get()>>0) & 0xff
|
||||||
|
case 33: // PB01
|
||||||
|
return uint8(sam.PORT.PINCFG1_0.Get()>>8) & 0xff
|
||||||
|
case 34: // PB02
|
||||||
|
return uint8(sam.PORT.PINCFG1_0.Get()>>16) & 0xff
|
||||||
|
case 35: // PB03
|
||||||
|
return uint8(sam.PORT.PINCFG1_0.Get()>>24) & 0xff
|
||||||
|
case 37: // PB04
|
||||||
|
return uint8(sam.PORT.PINCFG1_4.Get()>>0) & 0xff
|
||||||
|
case 38: // PB05
|
||||||
|
return uint8(sam.PORT.PINCFG1_4.Get()>>8) & 0xff
|
||||||
|
case 39: // PB06
|
||||||
|
return uint8(sam.PORT.PINCFG1_4.Get()>>16) & 0xff
|
||||||
|
case 40: // PB07
|
||||||
|
return uint8(sam.PORT.PINCFG1_4.Get()>>24) & 0xff
|
||||||
|
case 41: // PB08
|
||||||
|
return uint8(sam.PORT.PINCFG1_8.Get()>>0) & 0xff
|
||||||
|
case 42: // PB09
|
||||||
|
return uint8(sam.PORT.PINCFG1_8.Get()>>8) & 0xff
|
||||||
|
case 43: // PB10
|
||||||
|
return uint8(sam.PORT.PINCFG1_8.Get()>>16) & 0xff
|
||||||
|
case 44: // PB11
|
||||||
|
return uint8(sam.PORT.PINCFG1_8.Get()>>24) & 0xff
|
||||||
|
case 45: // PB12
|
||||||
|
return uint8(sam.PORT.PINCFG1_12.Get()>>0) & 0xff
|
||||||
|
case 46: // PB13
|
||||||
|
return uint8(sam.PORT.PINCFG1_12.Get()>>8) & 0xff
|
||||||
|
case 47: // PB14
|
||||||
|
return uint8(sam.PORT.PINCFG1_12.Get()>>16) & 0xff
|
||||||
|
case 48: // PB15
|
||||||
|
return uint8(sam.PORT.PINCFG1_12.Get()>>24) & 0xff
|
||||||
|
case 49: // PB16
|
||||||
|
return uint8(sam.PORT.PINCFG1_16.Get()>>0) & 0xff
|
||||||
|
case 50: // PB17
|
||||||
|
return uint8(sam.PORT.PINCFG1_16.Get()>>8) & 0xff
|
||||||
|
case 51: // PB18
|
||||||
|
return uint8(sam.PORT.PINCFG1_16.Get()>>16) & 0xff
|
||||||
|
case 52: // PB19
|
||||||
|
return uint8(sam.PORT.PINCFG1_16.Get()>>24) & 0xff
|
||||||
|
case 53: // PB20
|
||||||
|
return uint8(sam.PORT.PINCFG1_20.Get()>>0) & 0xff
|
||||||
|
case 54: // PB21
|
||||||
|
return uint8(sam.PORT.PINCFG1_20.Get()>>8) & 0xff
|
||||||
|
case 55: // PB22
|
||||||
|
return uint8(sam.PORT.PINCFG1_20.Get()>>16) & 0xff
|
||||||
|
case 56: // PB23
|
||||||
|
return uint8(sam.PORT.PINCFG1_20.Get()>>24) & 0xff
|
||||||
|
case 57: // PB24
|
||||||
|
return uint8(sam.PORT.PINCFG1_24.Get()>>0) & 0xff
|
||||||
|
case 58: // PB25
|
||||||
|
return uint8(sam.PORT.PINCFG1_24.Get()>>8) & 0xff
|
||||||
|
case 59: // PB26
|
||||||
|
return uint8(sam.PORT.PINCFG1_24.Get()>>16) & 0xff
|
||||||
|
case 60: // PB27
|
||||||
|
return uint8(sam.PORT.PINCFG1_24.Get()>>24) & 0xff
|
||||||
|
case 61: // PB28
|
||||||
|
return uint8(sam.PORT.PINCFG1_28.Get()>>0) & 0xff
|
||||||
|
case 62: // PB29
|
||||||
|
return uint8(sam.PORT.PINCFG1_28.Get()>>8) & 0xff
|
||||||
|
case 63: // PB30
|
||||||
|
return uint8(sam.PORT.PINCFG1_28.Get()>>16) & 0xff
|
||||||
|
case 64: // PB31
|
||||||
|
return uint8(sam.PORT.PINCFG1_28.Get()>>24) & 0xff
|
||||||
|
default:
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// setPinCfg sets the value for the correct PINCFG register for this pin.
|
||||||
|
func (p Pin) setPinCfg(val uint8) {
|
||||||
|
switch p {
|
||||||
|
case 0:
|
||||||
|
sam.PORT.PINCFG0_0.Set(val)
|
||||||
|
case 1:
|
||||||
|
sam.PORT.PINCFG0_1.Set(val)
|
||||||
|
case 2:
|
||||||
|
sam.PORT.PINCFG0_2.Set(val)
|
||||||
|
case 3:
|
||||||
|
sam.PORT.PINCFG0_3.Set(val)
|
||||||
|
case 4:
|
||||||
|
sam.PORT.PINCFG0_4.Set(val)
|
||||||
|
case 5:
|
||||||
|
sam.PORT.PINCFG0_5.Set(val)
|
||||||
|
case 6:
|
||||||
|
sam.PORT.PINCFG0_6.Set(val)
|
||||||
|
case 7:
|
||||||
|
sam.PORT.PINCFG0_7.Set(val)
|
||||||
|
case 8:
|
||||||
|
sam.PORT.PINCFG0_8.Set(val)
|
||||||
|
case 9:
|
||||||
|
sam.PORT.PINCFG0_9.Set(val)
|
||||||
|
case 10:
|
||||||
|
sam.PORT.PINCFG0_10.Set(val)
|
||||||
|
case 11:
|
||||||
|
sam.PORT.PINCFG0_11.Set(val)
|
||||||
|
case 12:
|
||||||
|
sam.PORT.PINCFG0_12.Set(val)
|
||||||
|
case 13:
|
||||||
|
sam.PORT.PINCFG0_13.Set(val)
|
||||||
|
case 14:
|
||||||
|
sam.PORT.PINCFG0_14.Set(val)
|
||||||
|
case 15:
|
||||||
|
sam.PORT.PINCFG0_15.Set(val)
|
||||||
|
case 16:
|
||||||
|
sam.PORT.PINCFG0_16.Set(val)
|
||||||
|
case 17:
|
||||||
|
sam.PORT.PINCFG0_17.Set(val)
|
||||||
|
case 18:
|
||||||
|
sam.PORT.PINCFG0_18.Set(val)
|
||||||
|
case 19:
|
||||||
|
sam.PORT.PINCFG0_19.Set(val)
|
||||||
|
case 20:
|
||||||
|
sam.PORT.PINCFG0_20.Set(val)
|
||||||
|
case 21:
|
||||||
|
sam.PORT.PINCFG0_21.Set(val)
|
||||||
|
case 22:
|
||||||
|
sam.PORT.PINCFG0_22.Set(val)
|
||||||
|
case 23:
|
||||||
|
sam.PORT.PINCFG0_23.Set(val)
|
||||||
|
case 24:
|
||||||
|
sam.PORT.PINCFG0_24.Set(val)
|
||||||
|
case 25:
|
||||||
|
sam.PORT.PINCFG0_25.Set(val)
|
||||||
|
case 26:
|
||||||
|
sam.PORT.PINCFG0_26.Set(val)
|
||||||
|
case 27:
|
||||||
|
sam.PORT.PINCFG0_27.Set(val)
|
||||||
|
case 28:
|
||||||
|
sam.PORT.PINCFG0_28.Set(val)
|
||||||
|
case 29:
|
||||||
|
sam.PORT.PINCFG0_29.Set(val)
|
||||||
|
case 30:
|
||||||
|
sam.PORT.PINCFG0_30.Set(val)
|
||||||
|
case 31:
|
||||||
|
sam.PORT.PINCFG0_31.Set(val)
|
||||||
|
case 32: // PB00
|
||||||
|
sam.PORT.PINCFG1_0.Set(sam.PORT.PINCFG1_0.Get()&^(0xff<<0) | (uint32(val) << 0))
|
||||||
|
case 33: // PB01
|
||||||
|
sam.PORT.PINCFG1_0.Set(sam.PORT.PINCFG1_0.Get()&^(0xff<<8) | (uint32(val) << 8))
|
||||||
|
case 34: // PB02
|
||||||
|
sam.PORT.PINCFG1_0.Set(sam.PORT.PINCFG1_0.Get()&^(0xff<<16) | (uint32(val) << 16))
|
||||||
|
case 35: // PB03
|
||||||
|
sam.PORT.PINCFG1_0.Set(sam.PORT.PINCFG1_0.Get()&^(0xff<<24) | (uint32(val) << 24))
|
||||||
|
case 36: // PB04
|
||||||
|
sam.PORT.PINCFG1_4.Set(sam.PORT.PINCFG1_4.Get()&^(0xff<<0) | (uint32(val) << 0))
|
||||||
|
case 37: // PB05
|
||||||
|
sam.PORT.PINCFG1_4.Set(sam.PORT.PINCFG1_4.Get()&^(0xff<<8) | (uint32(val) << 8))
|
||||||
|
case 38: // PB06
|
||||||
|
sam.PORT.PINCFG1_4.Set(sam.PORT.PINCFG1_4.Get()&^(0xff<<16) | (uint32(val) << 16))
|
||||||
|
case 39: // PB07
|
||||||
|
sam.PORT.PINCFG1_4.Set(sam.PORT.PINCFG1_4.Get()&^(0xff<<24) | (uint32(val) << 24))
|
||||||
|
case 40: // PB08
|
||||||
|
sam.PORT.PINCFG1_8.Set(sam.PORT.PINCFG1_8.Get()&^(0xff<<0) | (uint32(val) << 0))
|
||||||
|
case 41: // PB09
|
||||||
|
sam.PORT.PINCFG1_8.Set(sam.PORT.PINCFG1_8.Get()&^(0xff<<8) | (uint32(val) << 8))
|
||||||
|
case 42: // PB10
|
||||||
|
sam.PORT.PINCFG1_8.Set(sam.PORT.PINCFG1_8.Get()&^(0xff<<16) | (uint32(val) << 16))
|
||||||
|
case 43: // PB11
|
||||||
|
sam.PORT.PINCFG1_8.Set(sam.PORT.PINCFG1_8.Get()&^(0xff<<24) | (uint32(val) << 24))
|
||||||
|
case 44: // PB12
|
||||||
|
sam.PORT.PINCFG1_12.Set(sam.PORT.PINCFG1_12.Get()&^(0xff<<0) | (uint32(val) << 0))
|
||||||
|
case 45: // PB13
|
||||||
|
sam.PORT.PINCFG1_12.Set(sam.PORT.PINCFG1_12.Get()&^(0xff<<8) | (uint32(val) << 8))
|
||||||
|
case 46: // PB14
|
||||||
|
sam.PORT.PINCFG1_12.Set(sam.PORT.PINCFG1_12.Get()&^(0xff<<16) | (uint32(val) << 16))
|
||||||
|
case 47: // PB15
|
||||||
|
sam.PORT.PINCFG1_12.Set(sam.PORT.PINCFG1_12.Get()&^(0xff<<24) | (uint32(val) << 24))
|
||||||
|
case 48: // PB16
|
||||||
|
sam.PORT.PINCFG1_16.Set(sam.PORT.PINCFG1_16.Get()&^(0xff<<0) | (uint32(val) << 0))
|
||||||
|
case 49: // PB17
|
||||||
|
sam.PORT.PINCFG1_16.Set(sam.PORT.PINCFG1_16.Get()&^(0xff<<8) | (uint32(val) << 8))
|
||||||
|
case 50: // PB18
|
||||||
|
sam.PORT.PINCFG1_16.Set(sam.PORT.PINCFG1_16.Get()&^(0xff<<16) | (uint32(val) << 16))
|
||||||
|
case 51: // PB19
|
||||||
|
sam.PORT.PINCFG1_16.Set(sam.PORT.PINCFG1_16.Get()&^(0xff<<24) | (uint32(val) << 24))
|
||||||
|
case 52: // PB20
|
||||||
|
sam.PORT.PINCFG1_20.Set(sam.PORT.PINCFG1_20.Get()&^(0xff<<0) | (uint32(val) << 0))
|
||||||
|
case 53: // PB21
|
||||||
|
sam.PORT.PINCFG1_20.Set(sam.PORT.PINCFG1_20.Get()&^(0xff<<8) | (uint32(val) << 8))
|
||||||
|
case 54: // PB22
|
||||||
|
sam.PORT.PINCFG1_20.Set(sam.PORT.PINCFG1_20.Get()&^(0xff<<16) | (uint32(val) << 16))
|
||||||
|
case 55: // PB23
|
||||||
|
sam.PORT.PINCFG1_20.Set(sam.PORT.PINCFG1_20.Get()&^(0xff<<24) | (uint32(val) << 24))
|
||||||
|
case 56: // PB24
|
||||||
|
sam.PORT.PINCFG1_24.Set(sam.PORT.PINCFG1_24.Get()&^(0xff<<0) | (uint32(val) << 0))
|
||||||
|
case 57: // PB25
|
||||||
|
sam.PORT.PINCFG1_24.Set(sam.PORT.PINCFG1_24.Get()&^(0xff<<8) | (uint32(val) << 8))
|
||||||
|
case 58: // PB26
|
||||||
|
sam.PORT.PINCFG1_24.Set(sam.PORT.PINCFG1_24.Get()&^(0xff<<16) | (uint32(val) << 16))
|
||||||
|
case 59: // PB27
|
||||||
|
sam.PORT.PINCFG1_24.Set(sam.PORT.PINCFG1_24.Get()&^(0xff<<24) | (uint32(val) << 24))
|
||||||
|
case 60: // PB28
|
||||||
|
sam.PORT.PINCFG1_28.Set(sam.PORT.PINCFG1_28.Get()&^(0xff<<0) | (uint32(val) << 0))
|
||||||
|
case 61: // PB29
|
||||||
|
sam.PORT.PINCFG1_28.Set(sam.PORT.PINCFG1_28.Get()&^(0xff<<8) | (uint32(val) << 8))
|
||||||
|
case 62: // PB30
|
||||||
|
sam.PORT.PINCFG1_28.Set(sam.PORT.PINCFG1_28.Get()&^(0xff<<16) | (uint32(val) << 16))
|
||||||
|
case 63: // PB31
|
||||||
|
sam.PORT.PINCFG1_28.Set(sam.PORT.PINCFG1_28.Get()&^(0xff<<24) | (uint32(val) << 24))
|
||||||
|
}
|
||||||
|
}
|
302
src/runtime/runtime_atsamd51.go
Обычный файл
302
src/runtime/runtime_atsamd51.go
Обычный файл
|
@ -0,0 +1,302 @@
|
||||||
|
// +build sam,atsamd51
|
||||||
|
|
||||||
|
package runtime
|
||||||
|
|
||||||
|
import (
|
||||||
|
"device/arm"
|
||||||
|
"device/sam"
|
||||||
|
"machine"
|
||||||
|
)
|
||||||
|
|
||||||
|
type timeUnit int64
|
||||||
|
|
||||||
|
//go:export Reset_Handler
|
||||||
|
func main() {
|
||||||
|
preinit()
|
||||||
|
initAll()
|
||||||
|
callMain()
|
||||||
|
abort()
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
initClocks()
|
||||||
|
initRTC()
|
||||||
|
initSERCOMClocks()
|
||||||
|
initUSBClock()
|
||||||
|
initADCClock()
|
||||||
|
|
||||||
|
// connect to USB CDC interface
|
||||||
|
machine.UART0.Configure(machine.UARTConfig{})
|
||||||
|
}
|
||||||
|
|
||||||
|
func putchar(c byte) {
|
||||||
|
machine.UART0.WriteByte(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
func initClocks() {
|
||||||
|
// set flash wait state
|
||||||
|
sam.NVMCTRL.CTRLA.SetBits(0 << sam.NVMCTRL_CTRLA_RWS_Pos)
|
||||||
|
|
||||||
|
// software reset
|
||||||
|
sam.GCLK.CTRLA.SetBits(sam.GCLK_CTRLA_SWRST)
|
||||||
|
for sam.GCLK.SYNCBUSY.HasBits(sam.GCLK_SYNCBUSY_SWRST) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set OSCULP32K as source of Generic Clock Generator 3
|
||||||
|
// GCLK->GENCTRL[GENERIC_CLOCK_GENERATOR_XOSC32K].reg = GCLK_GENCTRL_SRC(GCLK_GENCTRL_SRC_OSCULP32K) | GCLK_GENCTRL_GENEN; //generic clock gen 3
|
||||||
|
sam.GCLK.GENCTRL3.Set((sam.GCLK_GENCTRL_SRC_OSCULP32K << sam.GCLK_GENCTRL_SRC_Pos) |
|
||||||
|
sam.GCLK_GENCTRL_GENEN)
|
||||||
|
for sam.GCLK.SYNCBUSY.HasBits(sam.GCLK_SYNCBUSY_GENCTRL3) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set OSCULP32K as source of Generic Clock Generator 0
|
||||||
|
sam.GCLK.GENCTRL0.Set((sam.GCLK_GENCTRL_SRC_OSCULP32K << sam.GCLK_GENCTRL_SRC_Pos) |
|
||||||
|
sam.GCLK_GENCTRL_GENEN)
|
||||||
|
for sam.GCLK.SYNCBUSY.HasBits(sam.GCLK_SYNCBUSY_GENCTRL0) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enable DFLL48M clock
|
||||||
|
sam.OSCCTRL.DFLLCTRLA.Set(0)
|
||||||
|
sam.OSCCTRL.DFLLMUL.Set((0x1 << sam.OSCCTRL_DFLLMUL_CSTEP_Pos) |
|
||||||
|
(0x1 << sam.OSCCTRL_DFLLMUL_FSTEP_Pos) |
|
||||||
|
(0x0 << sam.OSCCTRL_DFLLMUL_MUL_Pos))
|
||||||
|
for sam.OSCCTRL.DFLLSYNC.HasBits(sam.OSCCTRL_DFLLSYNC_DFLLMUL) {
|
||||||
|
}
|
||||||
|
|
||||||
|
sam.OSCCTRL.DFLLCTRLB.Set(0)
|
||||||
|
for sam.OSCCTRL.DFLLSYNC.HasBits(sam.OSCCTRL_DFLLSYNC_DFLLCTRLB) {
|
||||||
|
}
|
||||||
|
|
||||||
|
sam.OSCCTRL.DFLLCTRLA.SetBits(sam.OSCCTRL_DFLLCTRLA_ENABLE)
|
||||||
|
for sam.OSCCTRL.DFLLSYNC.HasBits(sam.OSCCTRL_DFLLSYNC_ENABLE) {
|
||||||
|
}
|
||||||
|
|
||||||
|
sam.OSCCTRL.DFLLVAL.Set(sam.OSCCTRL.DFLLVAL.Get())
|
||||||
|
for sam.OSCCTRL.DFLLSYNC.HasBits(sam.OSCCTRL_DFLLSYNC_DFLLVAL) {
|
||||||
|
}
|
||||||
|
|
||||||
|
sam.OSCCTRL.DFLLCTRLB.Set(sam.OSCCTRL_DFLLCTRLB_WAITLOCK |
|
||||||
|
sam.OSCCTRL_DFLLCTRLB_CCDIS |
|
||||||
|
sam.OSCCTRL_DFLLCTRLB_USBCRM)
|
||||||
|
for !sam.OSCCTRL.STATUS.HasBits(sam.OSCCTRL_STATUS_DFLLRDY) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// set GCLK7 to use DFLL48M as clock source
|
||||||
|
sam.GCLK.GENCTRL7.Set((sam.GCLK_GENCTRL_SRC_DFLL << sam.GCLK_GENCTRL_SRC_Pos) |
|
||||||
|
(24 << sam.GCLK_GENCTRL_DIVSEL_Pos) |
|
||||||
|
sam.GCLK_GENCTRL_GENEN)
|
||||||
|
for sam.GCLK.SYNCBUSY.HasBits(sam.GCLK_SYNCBUSY_GENCTRL7) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up the PLLs
|
||||||
|
|
||||||
|
// Set PLL0 at 120MHz
|
||||||
|
sam.GCLK.PCHCTRL1.Set(sam.GCLK_PCHCTRL_CHEN |
|
||||||
|
(sam.GCLK_PCHCTRL_GEN_GCLK7 << sam.GCLK_PCHCTRL_GEN_Pos))
|
||||||
|
|
||||||
|
sam.OSCCTRL.DPLLRATIO0.Set((0x0 << sam.OSCCTRL_DPLLRATIO_LDRFRAC_Pos) |
|
||||||
|
(59 << sam.OSCCTRL_DPLLRATIO_LDR_Pos))
|
||||||
|
for sam.OSCCTRL.DPLLSYNCBUSY0.HasBits(sam.OSCCTRL_DPLLSYNCBUSY_DPLLRATIO) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// MUST USE LBYPASS DUE TO BUG IN REV A OF SAMD51, via Adafruit lib.
|
||||||
|
sam.OSCCTRL.DPLLCTRLB0.Set((sam.OSCCTRL_DPLLCTRLB_REFCLK_GCLK << sam.OSCCTRL_DPLLCTRLB_REFCLK_Pos) |
|
||||||
|
sam.OSCCTRL_DPLLCTRLB_LBYPASS)
|
||||||
|
|
||||||
|
sam.OSCCTRL.DPLLCTRLA0.Set(sam.OSCCTRL_DPLLCTRLA_ENABLE)
|
||||||
|
for !sam.OSCCTRL.DPLLSTATUS0.HasBits(sam.OSCCTRL_DPLLSTATUS_CLKRDY) ||
|
||||||
|
!sam.OSCCTRL.DPLLSTATUS0.HasBits(sam.OSCCTRL_DPLLSTATUS_LOCK) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// // Set PLL1 to 100MHz
|
||||||
|
sam.GCLK.PCHCTRL2.Set(sam.GCLK_PCHCTRL_CHEN |
|
||||||
|
(sam.GCLK_PCHCTRL_GEN_GCLK7 << sam.GCLK_PCHCTRL_GEN_Pos))
|
||||||
|
|
||||||
|
sam.OSCCTRL.DPLLRATIO1.Set((0x0 << sam.OSCCTRL_DPLLRATIO_LDRFRAC_Pos) |
|
||||||
|
(49 << sam.OSCCTRL_DPLLRATIO_LDR_Pos)) // this means 100 Mhz?
|
||||||
|
for sam.OSCCTRL.DPLLSYNCBUSY1.HasBits(sam.OSCCTRL_DPLLSYNCBUSY_DPLLRATIO) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// // MUST USE LBYPASS DUE TO BUG IN REV A OF SAMD51
|
||||||
|
sam.OSCCTRL.DPLLCTRLB1.Set((sam.OSCCTRL_DPLLCTRLB_REFCLK_GCLK << sam.OSCCTRL_DPLLCTRLB_REFCLK_Pos) |
|
||||||
|
sam.OSCCTRL_DPLLCTRLB_LBYPASS)
|
||||||
|
|
||||||
|
sam.OSCCTRL.DPLLCTRLA1.Set(sam.OSCCTRL_DPLLCTRLA_ENABLE)
|
||||||
|
// for !sam.OSCCTRL.DPLLSTATUS1.HasBits(sam.OSCCTRL_DPLLSTATUS_CLKRDY) ||
|
||||||
|
// !sam.OSCCTRL.DPLLSTATUS1.HasBits(sam.OSCCTRL_DPLLSTATUS_LOCK) {
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Set up the peripheral clocks
|
||||||
|
// Set 48MHZ CLOCK FOR USB
|
||||||
|
sam.GCLK.GENCTRL1.Set((sam.GCLK_GENCTRL_SRC_DFLL << sam.GCLK_GENCTRL_SRC_Pos) |
|
||||||
|
sam.GCLK_GENCTRL_IDC |
|
||||||
|
sam.GCLK_GENCTRL_GENEN)
|
||||||
|
for sam.GCLK.SYNCBUSY.HasBits(sam.GCLK_SYNCBUSY_GENCTRL1) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// // Set 100MHZ CLOCK FOR OTHER PERIPHERALS
|
||||||
|
// sam.GCLK.GENCTRL2.Set((sam.GCLK_GENCTRL_SRC_DPLL1 << sam.GCLK_GENCTRL_SRC_Pos) |
|
||||||
|
// sam.GCLK_GENCTRL_IDC |
|
||||||
|
// sam.GCLK_GENCTRL_GENEN)
|
||||||
|
// for sam.GCLK.SYNCBUSY.HasBits(sam.GCLK_SYNCBUSY_GENCTRL2) {
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Set 12MHZ CLOCK FOR DAC
|
||||||
|
sam.GCLK.GENCTRL4.Set((sam.GCLK_GENCTRL_SRC_DFLL << sam.GCLK_GENCTRL_SRC_Pos) |
|
||||||
|
sam.GCLK_GENCTRL_IDC |
|
||||||
|
(4 << sam.GCLK_GENCTRL_DIVSEL_Pos) |
|
||||||
|
sam.GCLK_GENCTRL_GENEN)
|
||||||
|
for sam.GCLK.SYNCBUSY.HasBits(sam.GCLK_SYNCBUSY_GENCTRL4) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// // Set up main clock
|
||||||
|
sam.GCLK.GENCTRL0.Set((sam.GCLK_GENCTRL_SRC_DPLL0 << sam.GCLK_GENCTRL_SRC_Pos) |
|
||||||
|
sam.GCLK_GENCTRL_IDC |
|
||||||
|
sam.GCLK_GENCTRL_GENEN)
|
||||||
|
for sam.GCLK.SYNCBUSY.HasBits(sam.GCLK_SYNCBUSY_GENCTRL0) {
|
||||||
|
}
|
||||||
|
|
||||||
|
sam.MCLK.CPUDIV.Set(sam.MCLK_CPUDIV_DIV_DIV1)
|
||||||
|
|
||||||
|
// Use the LDO regulator by default
|
||||||
|
sam.SUPC.VREG.ClearBits(sam.SUPC_VREG_SEL)
|
||||||
|
|
||||||
|
// Start up the "Debug Watchpoint and Trace" unit, so that we can use
|
||||||
|
// it's 32bit cycle counter for timing.
|
||||||
|
//CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
|
||||||
|
//DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
|
||||||
|
}
|
||||||
|
|
||||||
|
func initRTC() {
|
||||||
|
// turn on digital interface clock
|
||||||
|
sam.MCLK.APBAMASK.SetBits(sam.MCLK_APBAMASK_RTC_)
|
||||||
|
|
||||||
|
// disable RTC
|
||||||
|
sam.RTC_MODE0.CTRLA.ClearBits(sam.RTC_MODE0_CTRLA_ENABLE)
|
||||||
|
//sam.RTC_MODE0.CTRLA.Set(0)
|
||||||
|
for sam.RTC_MODE0.SYNCBUSY.HasBits(sam.RTC_MODE0_SYNCBUSY_ENABLE) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// reset RTC
|
||||||
|
sam.RTC_MODE0.CTRLA.SetBits(sam.RTC_MODE0_CTRLA_SWRST)
|
||||||
|
for sam.RTC_MODE0.SYNCBUSY.HasBits(sam.RTC_MODE0_SYNCBUSY_SWRST) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// set to use ulp 32k oscillator
|
||||||
|
sam.OSC32KCTRL.OSCULP32K.Set(sam.OSC32KCTRL_OSCULP32K_EN32K)
|
||||||
|
sam.OSC32KCTRL.RTCCTRL.Set(sam.OSC32KCTRL_RTCCTRL_RTCSEL_ULP32K)
|
||||||
|
|
||||||
|
// set Mode0 to 32-bit counter (mode 0) with prescaler 1 and GCLK2 is 32KHz/1
|
||||||
|
sam.RTC_MODE0.CTRLA.Set((sam.RTC_MODE0_CTRLA_MODE_COUNT32 << sam.RTC_MODE0_CTRLA_MODE_Pos) |
|
||||||
|
(sam.RTC_MODE0_CTRLA_PRESCALER_DIV1 << sam.RTC_MODE0_CTRLA_PRESCALER_Pos) |
|
||||||
|
(sam.RTC_MODE0_CTRLA_COUNTSYNC))
|
||||||
|
|
||||||
|
// re-enable RTC
|
||||||
|
sam.RTC_MODE0.CTRLA.SetBits(sam.RTC_MODE0_CTRLA_ENABLE)
|
||||||
|
for sam.RTC_MODE0.SYNCBUSY.HasBits(sam.RTC_MODE0_SYNCBUSY_ENABLE) {
|
||||||
|
}
|
||||||
|
|
||||||
|
arm.SetPriority(sam.IRQ_RTC, 0xc0)
|
||||||
|
arm.EnableIRQ(sam.IRQ_RTC)
|
||||||
|
}
|
||||||
|
|
||||||
|
func waitForSync() {
|
||||||
|
// for sam.GCLK.STATUS.HasBits(sam.GCLK_STATUS_SYNCBUSY) {
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
// treat all ticks params coming from runtime as being in microseconds
|
||||||
|
const tickMicros = 1000
|
||||||
|
|
||||||
|
var (
|
||||||
|
timestamp timeUnit // ticks since boottime
|
||||||
|
timerLastCounter uint64
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:volatile
|
||||||
|
type isrFlag bool
|
||||||
|
|
||||||
|
var timerWakeup isrFlag
|
||||||
|
|
||||||
|
const asyncScheduler = false
|
||||||
|
|
||||||
|
// sleepTicks should sleep for d number of microseconds.
|
||||||
|
func sleepTicks(d timeUnit) {
|
||||||
|
for d != 0 {
|
||||||
|
ticks() // update timestamp
|
||||||
|
ticks := uint32(d)
|
||||||
|
timerSleep(ticks)
|
||||||
|
d -= timeUnit(ticks)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ticks returns number of microseconds since start.
|
||||||
|
func ticks() timeUnit {
|
||||||
|
// request read of count
|
||||||
|
// sam.RTC_MODE0.READREQ.Set(sam.RTC_MODE0_READREQ_RREQ)
|
||||||
|
// waitForSync()
|
||||||
|
|
||||||
|
rtcCounter := (uint64(sam.RTC_MODE0.COUNT.Get()) * 305) / 10 // each counter tick == 30.5us
|
||||||
|
offset := (rtcCounter - timerLastCounter) // change since last measurement
|
||||||
|
timerLastCounter = rtcCounter
|
||||||
|
timestamp += timeUnit(offset) // TODO: not precise
|
||||||
|
return timestamp
|
||||||
|
}
|
||||||
|
|
||||||
|
// ticks are in microseconds
|
||||||
|
func timerSleep(ticks uint32) {
|
||||||
|
timerWakeup = false
|
||||||
|
if ticks < 30 {
|
||||||
|
// have to have at least one clock count
|
||||||
|
ticks = 30
|
||||||
|
}
|
||||||
|
|
||||||
|
// request read of count
|
||||||
|
// sam.RTC_MODE0.READREQ.Set(sam.RTC_MODE0_READREQ_RREQ)
|
||||||
|
// waitForSync()
|
||||||
|
|
||||||
|
// set compare value
|
||||||
|
cnt := sam.RTC_MODE0.COUNT.Get()
|
||||||
|
sam.RTC_MODE0.COMP0.Set(uint32(cnt) + (ticks * 10 / 305)) // each counter tick == 30.5us
|
||||||
|
waitForSync()
|
||||||
|
|
||||||
|
// enable IRQ for CMP0 compare
|
||||||
|
sam.RTC_MODE0.INTENSET.SetBits(sam.RTC_MODE0_INTENSET_CMP0)
|
||||||
|
|
||||||
|
for !timerWakeup {
|
||||||
|
arm.Asm("wfi")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//go:export RTC_IRQHandler
|
||||||
|
func handleRTC() {
|
||||||
|
// disable IRQ for CMP0 compare
|
||||||
|
sam.RTC_MODE0.INTFLAG.SetBits(sam.RTC_MODE0_INTENSET_CMP0)
|
||||||
|
|
||||||
|
timerWakeup = true
|
||||||
|
}
|
||||||
|
|
||||||
|
func initUSBClock() {
|
||||||
|
// Turn on clock(s) for USB
|
||||||
|
//MCLK->APBBMASK.reg |= MCLK_APBBMASK_USB;
|
||||||
|
//MCLK->AHBMASK.reg |= MCLK_AHBMASK_USB;
|
||||||
|
sam.MCLK.APBBMASK.SetBits(sam.MCLK_APBBMASK_USB_)
|
||||||
|
sam.MCLK.AHBMASK.SetBits(sam.MCLK_AHBMASK_USB_)
|
||||||
|
|
||||||
|
// Put Generic Clock Generator 1 as source for USB
|
||||||
|
//GCLK->PCHCTRL[USB_GCLK_ID].reg = GCLK_PCHCTRL_GEN_GCLK1_Val | (1 << GCLK_PCHCTRL_CHEN_Pos);
|
||||||
|
sam.GCLK.PCHCTRL10.Set((sam.GCLK_PCHCTRL_GEN_GCLK1 << sam.GCLK_PCHCTRL_GEN_Pos) |
|
||||||
|
sam.GCLK_PCHCTRL_CHEN)
|
||||||
|
}
|
||||||
|
|
||||||
|
func initADCClock() {
|
||||||
|
// Turn on clocks for ADC0/ADC1.
|
||||||
|
sam.MCLK.APBDMASK.SetBits(sam.MCLK_APBDMASK_ADC0_)
|
||||||
|
sam.MCLK.APBDMASK.SetBits(sam.MCLK_APBDMASK_ADC1_)
|
||||||
|
|
||||||
|
// Put Generic Clock Generator 1 as source for ADC0 and ADC1.
|
||||||
|
sam.GCLK.PCHCTRL40.Set((sam.GCLK_PCHCTRL_GEN_GCLK1 << sam.GCLK_PCHCTRL_GEN_Pos) |
|
||||||
|
sam.GCLK_PCHCTRL_CHEN)
|
||||||
|
sam.GCLK.PCHCTRL41.Set((sam.GCLK_PCHCTRL_GEN_GCLK1 << sam.GCLK_PCHCTRL_GEN_Pos) |
|
||||||
|
sam.GCLK_PCHCTRL_CHEN)
|
||||||
|
}
|
43
src/runtime/runtime_atsamd51g19.go
Обычный файл
43
src/runtime/runtime_atsamd51g19.go
Обычный файл
|
@ -0,0 +1,43 @@
|
||||||
|
// +build sam,atsamd51,atsamd51g19
|
||||||
|
|
||||||
|
package runtime
|
||||||
|
|
||||||
|
import (
|
||||||
|
"device/sam"
|
||||||
|
)
|
||||||
|
|
||||||
|
func initSERCOMClocks() {
|
||||||
|
// Turn on clock to SERCOM0 for UART0
|
||||||
|
sam.MCLK.APBAMASK.SetBits(sam.MCLK_APBAMASK_SERCOM0_)
|
||||||
|
sam.GCLK.PCHCTRL7.Set((sam.GCLK_PCHCTRL_GEN_GCLK1 << sam.GCLK_PCHCTRL_GEN_Pos) |
|
||||||
|
sam.GCLK_PCHCTRL_CHEN)
|
||||||
|
|
||||||
|
// sets the "slow" clock shared by all SERCOM
|
||||||
|
sam.GCLK.PCHCTRL3.Set((sam.GCLK_PCHCTRL_GEN_GCLK1 << sam.GCLK_PCHCTRL_GEN_Pos) |
|
||||||
|
sam.GCLK_PCHCTRL_CHEN)
|
||||||
|
|
||||||
|
// Turn on clock to SERCOM1
|
||||||
|
sam.MCLK.APBAMASK.SetBits(sam.MCLK_APBAMASK_SERCOM1_)
|
||||||
|
sam.GCLK.PCHCTRL8.Set((sam.GCLK_PCHCTRL_GEN_GCLK1 << sam.GCLK_PCHCTRL_GEN_Pos) |
|
||||||
|
sam.GCLK_PCHCTRL_CHEN)
|
||||||
|
|
||||||
|
// Turn on clock to SERCOM2
|
||||||
|
sam.MCLK.APBBMASK.SetBits(sam.MCLK_APBBMASK_SERCOM2_)
|
||||||
|
sam.GCLK.PCHCTRL23.Set((sam.GCLK_PCHCTRL_GEN_GCLK1 << sam.GCLK_PCHCTRL_GEN_Pos) |
|
||||||
|
sam.GCLK_PCHCTRL_CHEN)
|
||||||
|
|
||||||
|
// Turn on clock to SERCOM3
|
||||||
|
sam.MCLK.APBBMASK.SetBits(sam.MCLK_APBBMASK_SERCOM3_)
|
||||||
|
sam.GCLK.PCHCTRL24.Set((sam.GCLK_PCHCTRL_GEN_GCLK1 << sam.GCLK_PCHCTRL_GEN_Pos) |
|
||||||
|
sam.GCLK_PCHCTRL_CHEN)
|
||||||
|
|
||||||
|
// Turn on clock to SERCOM4
|
||||||
|
sam.MCLK.APBDMASK.SetBits(sam.MCLK_APBDMASK_SERCOM4_)
|
||||||
|
sam.GCLK.PCHCTRL34.Set((sam.GCLK_PCHCTRL_GEN_GCLK1 << sam.GCLK_PCHCTRL_GEN_Pos) |
|
||||||
|
sam.GCLK_PCHCTRL_CHEN)
|
||||||
|
|
||||||
|
// Turn on clock to SERCOM5
|
||||||
|
sam.MCLK.APBDMASK.SetBits(sam.MCLK_APBDMASK_SERCOM5_)
|
||||||
|
sam.GCLK.PCHCTRL35.Set((sam.GCLK_PCHCTRL_GEN_GCLK1 << sam.GCLK_PCHCTRL_GEN_Pos) |
|
||||||
|
sam.GCLK_PCHCTRL_CHEN)
|
||||||
|
}
|
10
targets/atsamd51.ld
Обычный файл
10
targets/atsamd51.ld
Обычный файл
|
@ -0,0 +1,10 @@
|
||||||
|
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
FLASH_TEXT (rw) : ORIGIN = 0x00000000+0x4000, LENGTH = 0x00080000-0x4000 /* First 16KB used by bootloader */
|
||||||
|
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 0x00030000
|
||||||
|
}
|
||||||
|
|
||||||
|
_stack_size = 4K;
|
||||||
|
|
||||||
|
INCLUDE "targets/arm.ld"
|
15
targets/atsamd51g19a.json
Обычный файл
15
targets/atsamd51g19a.json
Обычный файл
|
@ -0,0 +1,15 @@
|
||||||
|
{
|
||||||
|
"inherits": ["cortex-m"],
|
||||||
|
"llvm-target": "armv7em-none-eabi",
|
||||||
|
"build-tags": ["atsamd51g19", "atsamd51", "sam"],
|
||||||
|
"cflags": [
|
||||||
|
"--target=armv7em-none-eabi",
|
||||||
|
"-Qunused-arguments"
|
||||||
|
],
|
||||||
|
"ldflags": [
|
||||||
|
"-T", "targets/atsamd51.ld"
|
||||||
|
],
|
||||||
|
"extra-files": [
|
||||||
|
"src/device/sam/atsamd51g19a.s"
|
||||||
|
]
|
||||||
|
}
|
5
targets/itsybitsy-m4.json
Обычный файл
5
targets/itsybitsy-m4.json
Обычный файл
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"inherits": ["atsamd51g19a"],
|
||||||
|
"build-tags": ["sam", "atsamd51g19a", "itsybitsy_m4"],
|
||||||
|
"flash": "bossac -d -i -e -w -v -R --offset=0x4000 {bin}"
|
||||||
|
}
|
Загрузка…
Создание таблицы
Сослаться в новой задаче