atsame54: add initial support for atsame54-xpro

Этот коммит содержится в:
sago35 2020-08-03 19:13:28 +09:00 коммит произвёл Ron Evans
родитель 6dd5666ed1
коммит bd212cc000
11 изменённых файлов: 3577 добавлений и 1 удалений

Просмотреть файл

@ -336,6 +336,8 @@ smoketest:
@$(MD5SUM) test.hex @$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=p1am-100 examples/blinky1 $(TINYGO) build -size short -o test.hex -target=p1am-100 examples/blinky1
@$(MD5SUM) test.hex @$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=atsame54-xpro examples/blinky1
@$(MD5SUM) test.hex
# test pwm # test pwm
$(TINYGO) build -size short -o test.hex -target=itsybitsy-m0 examples/pwm $(TINYGO) build -size short -o test.hex -target=itsybitsy-m0 examples/pwm
@$(MD5SUM) test.hex @$(MD5SUM) test.hex

Просмотреть файл

@ -43,7 +43,7 @@ See the [getting started instructions](https://tinygo.org/getting-started/) for
You can compile TinyGo programs for microcontrollers, WebAssembly and Linux. You can compile TinyGo programs for microcontrollers, WebAssembly and Linux.
The following 55 microcontroller boards are currently supported: The following 56 microcontroller boards are currently supported:
* [Adafruit Circuit Playground Bluefruit](https://www.adafruit.com/product/4333) * [Adafruit Circuit Playground Bluefruit](https://www.adafruit.com/product/4333)
* [Adafruit Circuit Playground Express](https://www.adafruit.com/product/3333) * [Adafruit Circuit Playground Express](https://www.adafruit.com/product/3333)
@ -77,6 +77,7 @@ The following 55 microcontroller boards are currently supported:
* [Game Boy Advance](https://en.wikipedia.org/wiki/Game_Boy_Advance) * [Game Boy Advance](https://en.wikipedia.org/wiki/Game_Boy_Advance)
* [Makerdiary nRF52840-MDK](https://wiki.makerdiary.com/nrf52840-mdk/) * [Makerdiary nRF52840-MDK](https://wiki.makerdiary.com/nrf52840-mdk/)
* [Makerdiary nRF52840-MDK USB Dongle](https://wiki.makerdiary.com/nrf52840-mdk-usb-dongle/) * [Makerdiary nRF52840-MDK USB Dongle](https://wiki.makerdiary.com/nrf52840-mdk-usb-dongle/)
* [Microchip SAM E54 Xplained Pro](https://www.microchip.com/developmenttools/productdetails/atsame54-xpro)
* [nice!nano](https://docs.nicekeyboards.com/#/nice!nano/) * [nice!nano](https://docs.nicekeyboards.com/#/nice!nano/)
* [Nintendo Switch](https://www.nintendo.com/switch/) * [Nintendo Switch](https://www.nintendo.com/switch/)
* [Nordic Semiconductor PCA10031](https://www.nordicsemi.com/eng/Products/nRF51-Dongle) * [Nordic Semiconductor PCA10031](https://www.nordicsemi.com/eng/Products/nRF51-Dongle)

71
src/device/sam/atsame5x-bitfields.go Обычный файл
Просмотреть файл

@ -0,0 +1,71 @@
// Hand created file. DO NOT DELETE.
// atsamd51x bitfield definitions that are not auto-generated by gen-device-svd.go
// +build sam,atsame5x
// These are the supported pchctrl function numberings on the atsamd51x
// See http://ww1.microchip.com/downloads/en/DeviceDoc/SAM_D5xE5x_Family_Data_Sheet_DS60001507F.pdf
// table 14-9
package sam
const (
PCHCTRL_GCLK_OSCCTRL_DFLL48 = 0 // DFLL48 input clock source
PCHCTRL_GCLK_OSCCTRL_FDPLL0 = 1 // Reference clock for FDPLL0
PCHCTRL_GCLK_OSCCTRL_FDPLL1 = 2 // Reference clock for FDPLL1
PCHCTRL_GCLK_OSCCTRL_FDPLL0_32K = 3 // FDPLL0 = 3 // 32KHz clock for internal lock timer
PCHCTRL_GCLK_OSCCTRL_FDPLL1_32K = 3 // FDPLL1 = 3 // 32KHz clock for internal lock timer
PCHCTRL_GCLK_SDHC0_SLOW = 3 // SDHC0 = 3 // Slow
PCHCTRL_GCLK_SDHC1_SLOW = 3 // SDHC1 = 3 // Slow
PCHCTRL_GCLK_SERCOMX_SLOW = 3 // GCLK_SERCOM[0..7]_SLOW = 3
PCHCTRL_GCLK_EIC = 4
PCHCTRL_GCLK_FREQM_MSR = 5 // FREQM Measure
PCHCTRL_GCLK_FREQM_REF = 6 // FREQM Reference
PCHCTRL_GCLK_SERCOM0_CORE = 7 // SERCOM0 Core
PCHCTRL_GCLK_SERCOM1_CORE = 8 // SERCOM1 Core
PCHCTRL_GCLK_TC0 = 9
PCHCTRL_GCLK_TC1 = 9 // TC0, TC1
PCHCTRL_GCLK_USB = 10 // USB
PCHCTRL_GCLK_EVSYS0 = 11
PCHCTRL_GCLK_EVSYS1 = 12
PCHCTRL_GCLK_EVSYS2 = 13
PCHCTRL_GCLK_EVSYS3 = 14
PCHCTRL_GCLK_EVSYS4 = 15
PCHCTRL_GCLK_EVSYS5 = 16
PCHCTRL_GCLK_EVSYS6 = 17
PCHCTRL_GCLK_EVSYS7 = 18
PCHCTRL_GCLK_EVSYS8 = 19
PCHCTRL_GCLK_EVSYS9 = 20
PCHCTRL_GCLK_EVSYS10 = 21
PCHCTRL_GCLK_EVSYS11 = 22
PCHCTRL_GCLK_SERCOM2_CORE = 23 // SERCOM2 Core
PCHCTRL_GCLK_SERCOM3_CORE = 24 // SERCOM3 Core
PCHCTRL_GCLK_TCC0 = 25
PCHCTRL_GCLK_TCC1 = 25 // TCC0, TCC1
PCHCTRL_GCLK_TC2 = 26
PCHCTRL_GCLK_TC3 = 26 // TC2, TC3
PCHCTRL_GCLK_CAN0 = 27 // CAN0
PCHCTRL_GCLK_CAN1 = 28 // CAN1
PCHCTRL_GCLK_TCC2 = 29
PCHCTRL_GCLK_TCC3 = 29 // TCC2, TCC3
PCHCTRL_GCLK_TC4 = 30
PCHCTRL_GCLK_TC5 = 30 // TC4, TC5
PCHCTRL_GCLK_PDEC = 31 // PDEC
PCHCTRL_GCLK_AC = 32 // AC
PCHCTRL_GCLK_CCL = 33 // CCL
PCHCTRL_GCLK_SERCOM4_CORE = 34 // SERCOM4 Core
PCHCTRL_GCLK_SERCOM5_CORE = 35 // SERCOM5 Core
PCHCTRL_GCLK_SERCOM6_CORE = 36 // SERCOM6 Core
PCHCTRL_GCLK_SERCOM7_CORE = 37 // SERCOM7 Core
PCHCTRL_GCLK_TCC4 = 38 // TCC4
PCHCTRL_GCLK_TC6 = 39
PCHCTRL_GCLK_TC7 = 39 // TC6, TC7
PCHCTRL_GCLK_ADC0 = 40 // ADC0
PCHCTRL_GCLK_ADC1 = 41 // ADC1
PCHCTRL_GCLK_DAC = 42 // DAC
PCHCTRL_GCLK_I2S0 = 43
PCHCTRL_GCLK_I2S1 = 44
PCHCTRL_GCLK_SDHC0 = 45 // SDHC0
PCHCTRL_GCLK_SDHC1 = 46 // SDHC1
PCHCTRL_GCLK_CM4_TRACE = 47 // CM4 Trace
)

330
src/machine/board_atsame54-xpro.go Обычный файл
Просмотреть файл

@ -0,0 +1,330 @@
// +build atsame54_xpro
package machine
import (
"device/sam"
"runtime/interrupt"
)
// Definition for compatibility, but not used
const RESET_MAGIC_VALUE = 0x00000000
const (
LED = PC18
BUTTON = PB31
)
const (
// https://ww1.microchip.com/downloads/en/DeviceDoc/70005321A.pdf
// Extension Header EXT1
EXT1_PIN3_ADC_P = PB04
EXT1_PIN4_ADC_N = PB05
EXT1_PIN5_GPIO1 = PA06
EXT1_PIN6_GPIO2 = PA07
EXT1_PIN7_PWM_P = PB08
EXT1_PIN8_PWM_N = PB09
EXT1_PIN9_IRQ = PB07
EXT1_PIN9_GPIO = PB07
EXT1_PIN10_SPI_SS_B = PA27
EXT1_PIN10_GPIO = PA27
EXT1_PIN11_TWI_SDA = PA22
EXT1_PIN12_TWI_SCL = PA23
EXT1_PIN13_UART_RX = PA05
EXT1_PIN14_UART_TX = PA04
EXT1_PIN15_SPI_SS_A = PB28
EXT1_PIN16_SPI_SDO = PB27
EXT1_PIN17_SPI_SDI = PB29
EXT1_PIN18_SPI_SCK = PB26
// Extension Header EXT2
EXT2_PIN3_ADC_P = PB00
EXT2_PIN4_ADC_N = PA03
EXT2_PIN5_GPIO1 = PB01
EXT2_PIN6_GPIO2 = PB06
EXT2_PIN7_PWM_P = PB14
EXT2_PIN8_PWM_N = PB15
EXT2_PIN9_IRQ = PD00
EXT2_PIN9_GPIO = PD00
EXT2_PIN10_SPI_SS_B = PB02
EXT2_PIN10_GPIO = PB02
EXT2_PIN11_TWI_SDA = PD08
EXT2_PIN12_TWI_SCL = PD09
EXT2_PIN13_UART_RX = PB17
EXT2_PIN14_UART_TX = PB16
EXT2_PIN15_SPI_SS_A = PC06
EXT2_PIN16_SPI_SDO = PC04
EXT2_PIN17_SPI_SDI = PC07
EXT2_PIN18_SPI_SCK = PC05
// Extension Header EXT3
EXT3_PIN3_ADC_P = PC02
EXT3_PIN4_ADC_N = PC03
EXT3_PIN5_GPIO1 = PC01
EXT3_PIN6_GPIO2 = PC10
EXT3_PIN7_PWM_P = PD10
EXT3_PIN8_PWM_N = PD11
EXT3_PIN9_IRQ = PC30
EXT3_PIN9_GPIO = PC30
EXT3_PIN10_SPI_SS_B = PC31
EXT3_PIN10_GPIO = PC31
EXT3_PIN11_TWI_SDA = PD08
EXT3_PIN12_TWI_SCL = PD09
EXT3_PIN13_UART_RX = PC23
EXT3_PIN14_UART_TX = PC22
EXT3_PIN15_SPI_SS_A = PC14
EXT3_PIN16_SPI_SDO = PC04
EXT3_PIN17_SPI_SDI = PC07
EXT3_PIN18_SPI_SCK = PC05
// SD_CARD
SD_CARD_MCDA0 = PB18
SD_CARD_MCDA1 = PB19
SD_CARD_MCDA2 = PB20
SD_CARD_MCDA3 = PB21
SD_CARD_MCCK = PA21
SD_CARD_MCCDA = PA20
SD_CARD_DETECT = PD20
SD_CARD_PROTECT = PD21
// I2C
I2C_SDA = PD08
I2C_SCL = PD09
// CAN
CAN0_TX = PA22
CAN0_RX = PA23
CAN1_STANDBY = PC13
CAN1_TX = PB12
CAN1_RX = PB13
CAN_STANDBY = CAN1_STANDBY
CAN_TX = CAN1_TX
CAN_RX = CAN1_RX
// PDEC
PDEC_PHASE_A = PC16
PDEC_PHASE_B = PC17
PDEC_INDEX = PC18
// PCC
PCC_I2C_SDA = PD08
PCC_I2C_SCL = PD09
PCC_VSYNC_DEN1 = PA12
PCC_HSYNC_DEN2 = PA13
PCC_CLK = PA14
PCC_XCLK = PA15
PCC_DATA00 = PA16
PCC_DATA01 = PA17
PCC_DATA02 = PA18
PCC_DATA03 = PA19
PCC_DATA04 = PA20
PCC_DATA05 = PA21
PCC_DATA06 = PA22
PCC_DATA07 = PA23
PCC_DATA08 = PB14
PCC_DATA09 = PB15
PCC_RESET = PC12
PCC_PWDN = PC11
// Ethernet
ETHERNET_TXCK = PA14
ETHERNET_TXEN = PA17
ETHERNET_TX0 = PA18
ETHERNET_TX1 = PA19
ETHERNET_RXER = PA15
ETHERNET_RX0 = PA13
ETHERNET_RX1 = PA12
ETHERNET_RXDV = PC20
ETHERNET_MDIO = PC12
ETHERNET_MDC = PC11
ETHERNET_INT = PD12
ETHERNET_RESET = PC21
PIN_QT_BUTTON = PA16
PIN_BTN0 = PB31
PIN_ETH_LED = PC15
PIN_LED0 = PC18
PIN_ADC_DAC = PA02
PIN_VBUS_DETECT = PC00
PIN_USB_ID = PC19
)
// UART0 aka USBCDC pins
const (
USBCDC_DM_PIN = PA24
USBCDC_DP_PIN = PA25
)
// UART pins
const (
// Extension Header EXT1
UART_TX_PIN = PA04 // TX : SERCOM0/PAD[0]
UART_RX_PIN = PA05 // RX : SERCOM0/PAD[1]
// Extension Header EXT2
UART2_TX_PIN = PB16 // TX : SERCOM5/PAD[0]
UART2_RX_PIN = PB17 // RX : SERCOM5/PAD[1]
// Extension Header EXT3
UART3_TX_PIN = PC22 // TX : SERCOM1/PAD[0]
UART3_RX_PIN = PC23 // RX : SERCOM1/PAD[1]
// Virtual COM Port
UART4_TX_PIN = PB25 // TX : SERCOM2/PAD[0]
UART4_RX_PIN = PB24 // RX : SERCOM2/PAD[1]
)
// I2C pins
const (
// Extension Header EXT1
SDA0_PIN = PA22 // SDA: SERCOM3/PAD[0]
SCL0_PIN = PA23 // SCL: SERCOM3/PAD[1]
// Extension Header EXT2
SDA1_PIN = PD08 // SDA: SERCOM7/PAD[0]
SCL1_PIN = PD09 // SCL: SERCOM7/PAD[1]
// Extension Header EXT3
SDA2_PIN = PD08 // SDA: SERCOM7/PAD[0]
SCL2_PIN = PD09 // SCL: SERCOM7/PAD[1]
// Data Gateway Interface
SDA_DGI_PIN = PD08 // SDA: SERCOM7/PAD[0]
SCL_DGI_PIN = PD09 // SCL: SERCOM7/PAD[1]
SDA_PIN = SDA0_PIN
SCL_PIN = SCL0_PIN
)
// SPI pins
const (
// Extension Header EXT1
SPI0_SCK_PIN = PB26 // SCK: SERCOM4/PAD[1]
SPI0_SDO_PIN = PB27 // SDO: SERCOM4/PAD[0]
SPI0_SDI_PIN = PB29 // SDI: SERCOM4/PAD[3]
SPI0_SS_PIN = PB28 // SS : SERCOM4/PAD[2]
// Extension Header EXT2
SPI1_SCK_PIN = PC05 // SCK: SERCOM6/PAD[1]
SPI1_SDO_PIN = PC04 // SDO: SERCOM6/PAD[0]
SPI1_SDI_PIN = PC07 // SDI: SERCOM6/PAD[3]
SPI1_SS_PIN = PC06 // SS : SERCOM6/PAD[2]
// Extension Header EXT3
SPI2_SCK_PIN = PC05 // SCK: SERCOM6/PAD[1]
SPI2_SDO_PIN = PC04 // SDO: SERCOM6/PAD[0]
SPI2_SDI_PIN = PC07 // SDI: SERCOM6/PAD[3]
SPI2_SS_PIN = PC14 // SS : GPIO
// Data Gateway Interface
SPI_DGI_SCK_PIN = PC05 // SCK: SERCOM6/PAD[1]
SPI_DGI_SDO_PIN = PC04 // SDO: SERCOM6/PAD[0]
SPI_DGI_SDI_PIN = PC07 // SDI: SERCOM6/PAD[3]
SPI_DGI_SS_PIN = PD01 // SS : GPIO
)
// USB CDC identifiers
const (
usb_STRING_PRODUCT = "SAM E54 Xplained Pro"
usb_STRING_MANUFACTURER = "Atmel"
)
var (
usb_VID uint16 = 0x03EB
usb_PID uint16 = 0x2404
)
// UART on the SAM E54 Xplained Pro
var (
// Extension Header EXT1
UART1 = UART{
Buffer: NewRingBuffer(),
Bus: sam.SERCOM0_USART_INT,
SERCOM: 0,
}
// Extension Header EXT2
UART2 = UART{
Buffer: NewRingBuffer(),
Bus: sam.SERCOM5_USART_INT,
SERCOM: 5,
}
// Extension Header EXT3
UART3 = UART{
Buffer: NewRingBuffer(),
Bus: sam.SERCOM1_USART_INT,
SERCOM: 1,
}
// EDBG Virtual COM Port
UART4 = UART{
Buffer: NewRingBuffer(),
Bus: sam.SERCOM2_USART_INT,
SERCOM: 2,
}
)
func init() {
UART1.Interrupt = interrupt.New(sam.IRQ_SERCOM0_2, UART1.handleInterrupt)
UART2.Interrupt = interrupt.New(sam.IRQ_SERCOM5_2, UART2.handleInterrupt)
UART3.Interrupt = interrupt.New(sam.IRQ_SERCOM1_2, UART3.handleInterrupt)
UART4.Interrupt = interrupt.New(sam.IRQ_SERCOM2_2, UART4.handleInterrupt)
}
// I2C on the SAM E54 Xplained Pro
var (
// Extension Header EXT1
I2C0 = I2C{
Bus: sam.SERCOM3_I2CM,
SERCOM: 3,
}
// Extension Header EXT2
I2C1 = I2C{
Bus: sam.SERCOM7_I2CM,
SERCOM: 7,
}
// Extension Header EXT3
I2C2 = I2C{
Bus: sam.SERCOM7_I2CM,
SERCOM: 7,
}
// Data Gateway Interface
I2C3 = I2C{
Bus: sam.SERCOM7_I2CM,
SERCOM: 7,
}
)
// SPI on the SAM E54 Xplained Pro
var (
// Extension Header EXT1
SPI0 = SPI{
Bus: sam.SERCOM4_SPIM,
SERCOM: 4,
}
// Extension Header EXT2
SPI1 = SPI{
Bus: sam.SERCOM6_SPIM,
SERCOM: 6,
}
// Extension Header EXT3
SPI2 = SPI{
Bus: sam.SERCOM6_SPIM,
SERCOM: 6,
}
// Data Gateway Interface
SPI3 = SPI{
Bus: sam.SERCOM6_SPIM,
SERCOM: 6,
}
)

59
src/machine/machine_atsame54p20.go Обычный файл
Просмотреть файл

@ -0,0 +1,59 @@
// +build sam,atsame5x,atsame54p20
// Peripheral abstraction layer for the atsame54.
//
// Datasheet:
// http://ww1.microchip.com/downloads/en/DeviceDoc/60001507C.pdf
//
package machine
import "device/sam"
const HSRAM_SIZE = 0x00040000
// This chip has five TCC peripherals, which have PWM as one feature.
var (
TCC0 = (*TCC)(sam.TCC0)
TCC1 = (*TCC)(sam.TCC1)
TCC2 = (*TCC)(sam.TCC2)
TCC3 = (*TCC)(sam.TCC3)
TCC4 = (*TCC)(sam.TCC4)
)
func (tcc *TCC) configureClock() {
// Turn on timer clocks used for TCC and use generic clock generator 0.
switch tcc.timer() {
case sam.TCC0:
sam.MCLK.APBBMASK.SetBits(sam.MCLK_APBBMASK_TCC0_)
sam.GCLK.PCHCTRL[sam.PCHCTRL_GCLK_TCC0].Set((sam.GCLK_PCHCTRL_GEN_GCLK0 << sam.GCLK_PCHCTRL_GEN_Pos) | sam.GCLK_PCHCTRL_CHEN)
case sam.TCC1:
sam.MCLK.APBBMASK.SetBits(sam.MCLK_APBBMASK_TCC1_)
sam.GCLK.PCHCTRL[sam.PCHCTRL_GCLK_TCC1].Set((sam.GCLK_PCHCTRL_GEN_GCLK0 << sam.GCLK_PCHCTRL_GEN_Pos) | sam.GCLK_PCHCTRL_CHEN)
case sam.TCC2:
sam.MCLK.APBCMASK.SetBits(sam.MCLK_APBCMASK_TCC2_)
sam.GCLK.PCHCTRL[sam.PCHCTRL_GCLK_TCC2].Set((sam.GCLK_PCHCTRL_GEN_GCLK0 << sam.GCLK_PCHCTRL_GEN_Pos) | sam.GCLK_PCHCTRL_CHEN)
case sam.TCC3:
sam.MCLK.APBCMASK.SetBits(sam.MCLK_APBCMASK_TCC3_)
sam.GCLK.PCHCTRL[sam.PCHCTRL_GCLK_TCC3].Set((sam.GCLK_PCHCTRL_GEN_GCLK0 << sam.GCLK_PCHCTRL_GEN_Pos) | sam.GCLK_PCHCTRL_CHEN)
case sam.TCC4:
sam.MCLK.APBDMASK.SetBits(sam.MCLK_APBDMASK_TCC4_)
sam.GCLK.PCHCTRL[sam.PCHCTRL_GCLK_TCC4].Set((sam.GCLK_PCHCTRL_GEN_GCLK0 << sam.GCLK_PCHCTRL_GEN_Pos) | sam.GCLK_PCHCTRL_CHEN)
}
}
func (tcc *TCC) timerNum() uint8 {
switch tcc.timer() {
case sam.TCC0:
return 0
case sam.TCC1:
return 1
case sam.TCC2:
return 2
case sam.TCC3:
return 3
case sam.TCC4:
return 4
default:
return 0x0f // should not happen
}
}

2696
src/machine/machine_atsame5x.go Обычный файл

Различия файлов не показаны, т.к. их слишком много Показать различия

53
src/runtime/runtime_atsame54p20.go Обычный файл
Просмотреть файл

@ -0,0 +1,53 @@
// +build sam,atsame5x,atsame54p20
package runtime
import (
"device/sam"
)
func initSERCOMClocks() {
// Turn on clock to SERCOM0 for UART0
sam.MCLK.APBAMASK.SetBits(sam.MCLK_APBAMASK_SERCOM0_)
sam.GCLK.PCHCTRL[sam.PCHCTRL_GCLK_SERCOM0_CORE].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.PCHCTRL[sam.PCHCTRL_GCLK_SERCOMX_SLOW].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.PCHCTRL[sam.PCHCTRL_GCLK_SERCOM1_CORE].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.PCHCTRL[sam.PCHCTRL_GCLK_SERCOM2_CORE].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.PCHCTRL[sam.PCHCTRL_GCLK_SERCOM3_CORE].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.PCHCTRL[sam.PCHCTRL_GCLK_SERCOM4_CORE].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.PCHCTRL[sam.PCHCTRL_GCLK_SERCOM5_CORE].Set((sam.GCLK_PCHCTRL_GEN_GCLK1 << sam.GCLK_PCHCTRL_GEN_Pos) |
sam.GCLK_PCHCTRL_CHEN)
// Turn on clock to SERCOM6
sam.MCLK.APBDMASK.SetBits(sam.MCLK_APBDMASK_SERCOM6_)
sam.GCLK.PCHCTRL[sam.PCHCTRL_GCLK_SERCOM6_CORE].Set((sam.GCLK_PCHCTRL_GEN_GCLK1 << sam.GCLK_PCHCTRL_GEN_Pos) |
sam.GCLK_PCHCTRL_CHEN)
// Turn on clock to SERCOM7
sam.MCLK.APBDMASK.SetBits(sam.MCLK_APBDMASK_SERCOM7_)
sam.GCLK.PCHCTRL[sam.PCHCTRL_GCLK_SERCOM7_CORE].Set((sam.GCLK_PCHCTRL_GEN_GCLK1 << sam.GCLK_PCHCTRL_GEN_Pos) |
sam.GCLK_PCHCTRL_CHEN)
}

338
src/runtime/runtime_atsame5x.go Обычный файл
Просмотреть файл

@ -0,0 +1,338 @@
// +build sam,atsame5x
package runtime
import (
"device/arm"
"device/sam"
"machine"
"runtime/interrupt"
"runtime/volatile"
)
type timeUnit int64
func postinit() {}
//export Reset_Handler
func main() {
preinit()
run()
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.GENCTRL[3].Set((sam.GCLK_GENCTRL_SRC_OSCULP32K << sam.GCLK_GENCTRL_SRC_Pos) |
sam.GCLK_GENCTRL_GENEN)
for sam.GCLK.SYNCBUSY.HasBits(sam.GCLK_SYNCBUSY_GENCTRL_GCLK3) {
}
// Set OSCULP32K as source of Generic Clock Generator 0
sam.GCLK.GENCTRL[0].Set((sam.GCLK_GENCTRL_SRC_OSCULP32K << sam.GCLK_GENCTRL_SRC_Pos) |
sam.GCLK_GENCTRL_GENEN)
for sam.GCLK.SYNCBUSY.HasBits(sam.GCLK_SYNCBUSY_GENCTRL_GCLK0) {
}
// 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 run at 2MHz, using DFLL48M as clock source
// GCLK7 = 48MHz / 24 = 2MHz
sam.GCLK.GENCTRL[7].Set((sam.GCLK_GENCTRL_SRC_DFLL << sam.GCLK_GENCTRL_SRC_Pos) |
(24 << sam.GCLK_GENCTRL_DIV_Pos) |
sam.GCLK_GENCTRL_GENEN)
for sam.GCLK.SYNCBUSY.HasBits(sam.GCLK_SYNCBUSY_GENCTRL_GCLK7) {
}
// Set up the PLLs
// Set PLL0 to run at 120MHz, using GCLK7 as clock source
sam.GCLK.PCHCTRL[1].Set(sam.GCLK_PCHCTRL_CHEN |
(sam.GCLK_PCHCTRL_GEN_GCLK7 << sam.GCLK_PCHCTRL_GEN_Pos))
// multiplier = 59 + 1 + (0/32) = 60
// PLL0 = 2MHz * 60 = 120MHz
sam.OSCCTRL.DPLL[0].DPLLRATIO.Set((0x0 << sam.OSCCTRL_DPLL_DPLLRATIO_LDRFRAC_Pos) |
(59 << sam.OSCCTRL_DPLL_DPLLRATIO_LDR_Pos))
for sam.OSCCTRL.DPLL[0].DPLLSYNCBUSY.HasBits(sam.OSCCTRL_DPLL_DPLLSYNCBUSY_DPLLRATIO) {
}
// MUST USE LBYPASS DUE TO BUG IN REV A OF SAMD51, via Adafruit lib.
sam.OSCCTRL.DPLL[0].DPLLCTRLB.Set((sam.OSCCTRL_DPLL_DPLLCTRLB_REFCLK_GCLK << sam.OSCCTRL_DPLL_DPLLCTRLB_REFCLK_Pos) |
sam.OSCCTRL_DPLL_DPLLCTRLB_LBYPASS)
sam.OSCCTRL.DPLL[0].DPLLCTRLA.Set(sam.OSCCTRL_DPLL_DPLLCTRLA_ENABLE)
for !sam.OSCCTRL.DPLL[0].DPLLSTATUS.HasBits(sam.OSCCTRL_DPLL_DPLLSTATUS_CLKRDY) ||
!sam.OSCCTRL.DPLL[0].DPLLSTATUS.HasBits(sam.OSCCTRL_DPLL_DPLLSTATUS_LOCK) {
}
// Set PLL1 to run at 100MHz, using GCLK7 as clock source
sam.GCLK.PCHCTRL[2].Set(sam.GCLK_PCHCTRL_CHEN |
(sam.GCLK_PCHCTRL_GEN_GCLK7 << sam.GCLK_PCHCTRL_GEN_Pos))
// multiplier = 49 + 1 + (0/32) = 50
// PLL1 = 2MHz * 50 = 100MHz
sam.OSCCTRL.DPLL[1].DPLLRATIO.Set((0x0 << sam.OSCCTRL_DPLL_DPLLRATIO_LDRFRAC_Pos) |
(49 << sam.OSCCTRL_DPLL_DPLLRATIO_LDR_Pos))
for sam.OSCCTRL.DPLL[1].DPLLSYNCBUSY.HasBits(sam.OSCCTRL_DPLL_DPLLSYNCBUSY_DPLLRATIO) {
}
// // MUST USE LBYPASS DUE TO BUG IN REV A OF SAMD51
sam.OSCCTRL.DPLL[1].DPLLCTRLB.Set((sam.OSCCTRL_DPLL_DPLLCTRLB_REFCLK_GCLK << sam.OSCCTRL_DPLL_DPLLCTRLB_REFCLK_Pos) |
sam.OSCCTRL_DPLL_DPLLCTRLB_LBYPASS)
sam.OSCCTRL.DPLL[1].DPLLCTRLA.Set(sam.OSCCTRL_DPLL_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.GENCTRL[1].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_GENCTRL_GCLK1) {
}
// // 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.GENCTRL[4].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_GENCTRL_GCLK4) {
}
// // Set up main clock
sam.GCLK.GENCTRL[0].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_GENCTRL_GCLK0) {
}
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.SetBits(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) {
}
irq := interrupt.New(sam.IRQ_RTC, func(interrupt.Interrupt) {
// disable IRQ for CMP0 compare
sam.RTC_MODE0.INTFLAG.SetBits(sam.RTC_MODE0_INTENSET_CMP0)
timerWakeup.Set(1)
})
irq.SetPriority(0xc0)
irq.Enable()
}
func waitForSync() {
for sam.RTC_MODE0.SYNCBUSY.HasBits(sam.RTC_MODE0_SYNCBUSY_COUNT) {
}
}
var (
timestamp timeUnit // ticks since boottime
timerLastCounter uint64
)
var timerWakeup volatile.Register8
const asyncScheduler = false
// ticksToNanoseconds converts RTC ticks (at 32768Hz) to nanoseconds.
func ticksToNanoseconds(ticks timeUnit) int64 {
// The following calculation is actually the following, but with both sides
// reduced to reduce the risk of overflow:
// ticks * 1e9 / 32768
return int64(ticks) * 1953125 / 64
}
// nanosecondsToTicks converts nanoseconds to RTC ticks (running at 32768Hz).
func nanosecondsToTicks(ns int64) timeUnit {
// The following calculation is actually the following, but with both sides
// reduced to reduce the risk of overflow:
// ns * 32768 / 1e9
return timeUnit(ns * 64 / 1953125)
}
// sleepTicks should sleep for d number of microseconds.
func sleepTicks(d timeUnit) {
for d != 0 {
ticks() // update timestamp
ticks := uint32(d)
if !timerSleep(ticks) {
return
}
d -= timeUnit(ticks)
}
}
// ticks returns number of microseconds since start.
func ticks() timeUnit {
waitForSync()
rtcCounter := uint64(sam.RTC_MODE0.COUNT.Get())
offset := (rtcCounter - timerLastCounter) // change since last measurement
timerLastCounter = rtcCounter
timestamp += timeUnit(offset)
return timestamp
}
// ticks are in microseconds
// Returns true if the timer completed.
// Returns false if another interrupt occured which requires an early return to scheduler.
func timerSleep(ticks uint32) bool {
timerWakeup.Set(0)
if ticks < 8 {
// due to delay waiting for the register value to sync, the minimum sleep value
// for the SAMD51 is 260us.
// For related info for SAMD21, see:
// https://community.atmel.com/comment/2507091#comment-2507091
ticks = 8
}
// request read of count
waitForSync()
// set compare value
cnt := sam.RTC_MODE0.COUNT.Get()
sam.RTC_MODE0.COMP[0].Set(uint32(cnt) + ticks)
// enable IRQ for CMP0 compare
sam.RTC_MODE0.INTENSET.SetBits(sam.RTC_MODE0_INTENSET_CMP0)
wait:
waitForEvents()
if timerWakeup.Get() != 0 {
return true
}
if hasScheduler {
// The interurpt may have awoken a goroutine, so bail out early.
// Disable IRQ for CMP0 compare.
sam.RTC_MODE0.INTENCLR.SetBits(sam.RTC_MODE0_INTENSET_CMP0)
return false
} else {
// This is running without a scheduler.
// The application expects this to sleep the whole time.
goto wait
}
}
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.PCHCTRL[sam.PCHCTRL_GCLK_USB].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.PCHCTRL[sam.PCHCTRL_GCLK_ADC0].Set((sam.GCLK_PCHCTRL_GEN_GCLK1 << sam.GCLK_PCHCTRL_GEN_Pos) |
sam.GCLK_PCHCTRL_CHEN)
sam.GCLK.PCHCTRL[sam.PCHCTRL_GCLK_ADC1].Set((sam.GCLK_PCHCTRL_GEN_GCLK1 << sam.GCLK_PCHCTRL_GEN_Pos) |
sam.GCLK_PCHCTRL_CHEN)
}
func waitForEvents() {
arm.Asm("wfe")
}

6
targets/atsame54-xpro.json Обычный файл
Просмотреть файл

@ -0,0 +1,6 @@
{
"inherits": ["atsame54p20a"],
"build-tags": ["atsame54_xpro"],
"flash-method": "openocd",
"openocd-interface": "cmsis-dap"
}

10
targets/atsame54p20a.json Обычный файл
Просмотреть файл

@ -0,0 +1,10 @@
{
"inherits": ["cortex-m4"],
"build-tags": ["sam", "atsame5x", "atsame54p20", "atsame54p20a"],
"linkerscript": "targets/atsame5xx20-no-bootloader.ld",
"extra-files": [
"src/device/sam/atsame54p20a.s"
],
"openocd-transport": "swd",
"openocd-target": "atsame5x"
}

10
targets/atsame5xx20-no-bootloader.ld Обычный файл
Просмотреть файл

@ -0,0 +1,10 @@
MEMORY
{
FLASH_TEXT (rw) : ORIGIN = 0x00000000+0x0000, LENGTH = 0x00100000-0x0000
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 0x00040000
}
_stack_size = 4K;
INCLUDE "targets/arm.ld"