diff options
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | README.md | 3 | ||||
-rw-r--r-- | src/machine/board_pyportal.go | 151 | ||||
-rw-r--r-- | src/machine/machine_atsamd51.go | 61 | ||||
-rw-r--r-- | src/machine/machine_atsamd51g19.go | 45 | ||||
-rw-r--r-- | src/machine/machine_atsamd51j19.go | 50 | ||||
-rw-r--r-- | src/machine/machine_atsamd51j20.go | 58 | ||||
-rw-r--r-- | src/runtime/runtime_atsamd51j20.go | 43 | ||||
-rw-r--r-- | targets/atsamd51j20a.json | 13 | ||||
-rw-r--r-- | targets/pyportal.json | 8 |
10 files changed, 387 insertions, 47 deletions
@@ -240,6 +240,8 @@ smoketest: @$(MD5SUM) test.hex $(TINYGO) build -size short -o test.hex -target=metro-m4-airlift examples/blinky1 @$(MD5SUM) test.hex + $(TINYGO) build -size short -o test.hex -target=pyportal examples/blinky1 + @$(MD5SUM) test.hex $(TINYGO) build -size short -o test.hex -target=nucleo-f103rb examples/blinky1 @$(MD5SUM) test.hex $(TINYGO) build -size short -o test.hex -target=pinetime-devkit0 examples/blinky1 @@ -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. -The following 22 microcontroller boards are currently supported: +The following 25 microcontroller boards are currently supported: * [Adafruit Circuit Playground Express](https://www.adafruit.com/product/3333) * [Adafruit Circuit Playground Bluefruit](https://www.adafruit.com/product/4333) @@ -53,6 +53,7 @@ The following 22 microcontroller boards are currently supported: * [Adafruit ItsyBitsy M4](https://www.adafruit.com/product/3800) * [Adafruit Metro M4 Express Airlift](https://www.adafruit.com/product/4000) * [Adafruit PyBadge](https://www.adafruit.com/product/4200) +* [Adafruit PyPortal](https://www.adafruit.com/product/4116) * [Adafruit Trinket M0](https://www.adafruit.com/product/3500) * [Arduino Nano33 IoT](https://store.arduino.cc/nano-33-iot) * [Arduino Uno](https://store.arduino.cc/arduino-uno-rev3) diff --git a/src/machine/board_pyportal.go b/src/machine/board_pyportal.go new file mode 100644 index 000000000..db119265c --- /dev/null +++ b/src/machine/board_pyportal.go @@ -0,0 +1,151 @@ +// +build sam,atsamd51,pyportal + +package machine + +import ( + "device/sam" +) + +// used to reset into bootloader +const RESET_MAGIC_VALUE = 0xf01669ef + +// GPIO Pins +const ( + D0 = PB13 // NINA_RX + D1 = PB12 // NINA_TX + D2 = PB22 // built-in neopixel + D3 = PA04 // PWM available + D4 = PA05 // PWM available + D5 = PB16 // NINA_ACK + D6 = PB15 // NINA_GPIO0 + D7 = PB17 // NINA_RESETN + D8 = PB14 // NINA_CS + D9 = PB04 // TFT_RD + D10 = PB05 // TFT_DC + D11 = PB06 // TFT_CS + D12 = PB07 // TFT_TE + D13 = PB23 // built-in LED + D24 = PA00 // TFT_RESET + D25 = PB31 // TFT_BACKLIGHT + D26 = PB09 // TFT_WR + D27 = PB02 // SDA + D28 = PB03 // SCL + D29 = PA12 // MOSI + D30 = PA13 // SCK + D31 = PA14 // MISO + D32 = PB30 // SD_CS + D33 = PA01 // SD_CARD_DETECT + D34 = PA16 // LCD_DATA0 + D35 = PA17 // LCD_DATA1 + D36 = PA18 // LCD_DATA2 + D37 = PA19 // LCD_DATA3 + D38 = PA20 // LCD_DATA4 + D39 = PA21 // LCD_DATA5 + D40 = PA22 // LCD_DATA6 + D41 = PA23 // LCD_DATA7 + D42 = PB10 // QSPI + D43 = PB11 // QSPI + D44 = PA08 // QSPI + D45 = PA09 // QSPI + D46 = PA10 // QSPI + D47 = PA11 // QSPI + D50 = PA02 // speaker amplifier shutdown + D51 = PA15 // NINA_RTS + + NINA_CS = D8 + NINA_ACK = D5 + NINA_GPIO0 = D6 + NINA_RESETN = D7 + + NINA_TX = D1 + NINA_RX = D0 + NINA_RTS = D51 + + LCD_DATA0 = D34 + + TFT_RD = D9 + TFT_DC = D10 + TFT_CS = D11 + TFT_TE = D12 + TFT_RESET = D24 + TFT_BACKLIGHT = D25 + TFT_WR = D26 + + NEOPIXEL = D2 + SPK_SD = D50 +) + +// Analog pins +const ( + A0 = PA02 // ADC0/AIN[0] + A1 = D3 // ADC0/AIN[4] + A2 = PA07 // ADC0/AIN[7] + A3 = D4 // ADC0/AIN[5] + A4 = PB00 // ADC0/AIN[12] + A5 = PB01 // ADC0/AIN[13] + A6 = PA06 // ADC0/AIN[6] + A7 = PB08 // ADC1/AIN[0] + + AUDIO_OUT = A0 + LIGHT = A2 + TOUCH_YD = A4 + TOUCH_XL = A5 + TOUCH_YU = A6 + TOUCH_XR = A7 +) + +const ( + LED = D13 +) + +// UART0 aka USBCDC pins +const ( + USBCDC_DM_PIN = PA24 + USBCDC_DP_PIN = PA25 +) + +// TODO: add configuration for UART on SERCOM4 that is connected to TX/RX of ESP32 +const ( + UART_TX_PIN = NoPin + UART_RX_PIN = NoPin +) + +// I2C pins +const ( + SDA_PIN = PB02 // SDA: SERCOM2/PAD[0] + SCL_PIN = PB03 // SCL: SERCOM2/PAD[1] +) + +// I2C on the PyPortal. +var ( + I2C0 = I2C{Bus: sam.SERCOM5_I2CM, + SDA: SDA_PIN, + SCL: SCL_PIN, + PinMode: PinSERCOMAlt} +) + +// SPI pins +const ( + SPI0_SCK_PIN = PA13 // SCK: SERCOM1/PAD[1] + SPI0_MOSI_PIN = PA12 // MOSI: SERCOM1/PAD[3] + SPI0_MISO_PIN = PA14 // MISO: SERCOM1/PAD[2] + + NINA_MOSI = SPI0_MOSI_PIN + NINA_MISO = SPI0_MISO_PIN + NINA_SCK = SPI0_SCK_PIN +) + +// SPI on the PyPortal. +var ( + SPI0 = SPI{Bus: sam.SERCOM2_SPIM, + SCK: SPI0_SCK_PIN, + MOSI: SPI0_MOSI_PIN, + MISO: SPI0_MISO_PIN, + DOpad: spiTXPad0SCK1, + DIpad: sercomRXPad2, + MISOPinMode: PinSERCOM, + MOSIPinMode: PinSERCOM, + SCKPinMode: PinSERCOM, + } + NINA_SPI = SPI0 +) diff --git a/src/machine/machine_atsamd51.go b/src/machine/machine_atsamd51.go index 02de1941a..e1ba148dc 100644 --- a/src/machine/machine_atsamd51.go +++ b/src/machine/machine_atsamd51.go @@ -449,16 +449,20 @@ func (a ADC) getADCChannel() uint8 { return 6 case PA07: return 7 + case PB00: + return 12 + case PB01: + return 13 case PB02: - return 10 + return 14 case PB03: - return 11 + return 15 case PA09: return 17 case PA11: return 19 default: - return 0 + panic("Invalid ADC pin") } } @@ -1054,19 +1058,6 @@ func (spi SPI) Transfer(w byte) (byte, error) { // PWM const period = 0xFFFF -// InitPWM initializes the PWM interface. -func InitPWM() { - // turn on timer clocks used for PWM - sam.MCLK.APBBMASK.SetBits(sam.MCLK_APBBMASK_TCC0_ | sam.MCLK_APBBMASK_TCC1_) - sam.MCLK.APBCMASK.SetBits(sam.MCLK_APBCMASK_TCC2_) - - //use clock generator 0 - sam.GCLK.PCHCTRL[25].Set((sam.GCLK_PCHCTRL_GEN_GCLK0 << sam.GCLK_PCHCTRL_GEN_Pos) | - sam.GCLK_PCHCTRL_CHEN) - sam.GCLK.PCHCTRL[29].Set((sam.GCLK_PCHCTRL_GEN_GCLK0 << sam.GCLK_PCHCTRL_GEN_Pos) | - sam.GCLK_PCHCTRL_CHEN) -} - // Configure configures a PWM pin for output. func (pwm PWM) Configure() { // Set pin as output @@ -1181,34 +1172,6 @@ func (pwm PWM) setPinCfg(val uint8) { pwm.Pin.setPinCfg(val) } -// getTimer returns the timer to be used for PWM on this pin -func (pwm PWM) getTimer() *sam.TCC_Type { - switch pwm.Pin { - case PA16: - return sam.TCC1 - case PA17: - return sam.TCC1 - case PA14: - return sam.TCC2 - case PA15: - return sam.TCC2 - case PA18: - return sam.TCC1 - case PA19: - return sam.TCC1 - case PA20: - return sam.TCC0 - case PA21: - return sam.TCC0 - case PA23: - return sam.TCC0 - case PA22: - return sam.TCC0 - default: - return nil // not supported on this pin - } -} - // setChannel sets the value for the correct channel for PWM on this pin func (pwm PWM) setChannel(val uint32) { switch pwm.Pin { @@ -1232,6 +1195,8 @@ func (pwm PWM) setChannel(val uint32) { pwm.getTimer().CC[3].Set(val) case PA22: pwm.getTimer().CC[2].Set(val) + case PB31: + pwm.getTimer().CC[1].Set(val) default: return // not supported on this pin } @@ -1260,6 +1225,8 @@ func (pwm PWM) setChannelBuffer(val uint32) { pwm.getTimer().CCBUF[3].Set(val) case PA22: pwm.getTimer().CCBUF[2].Set(val) + case PB31: + pwm.getTimer().CCBUF[1].Set(val) default: return // not supported on this pin } @@ -1288,6 +1255,8 @@ func (pwm PWM) getMux() PinMode { return PinPWMG case PA22: return PinPWMG + case PB31: + return PinPWMF default: return 0 // not supported on this pin } @@ -2049,14 +2018,14 @@ func setEPINTENSET(ep uint32, val uint8) { sam.USB_DEVICE.DEVICE_ENDPOINT[ep].EPINTENSET.Set(val) } -// ResetProcessor should perform a system reset in preperation +// ResetProcessor should perform a system reset in preparation // to switch to the bootloader to flash new firmware. func ResetProcessor() { arm.DisableInterrupts() // Perform magic reset into bootloader, as mentioned in // https://github.com/arduino/ArduinoCore-samd/issues/197 - *(*uint32)(unsafe.Pointer(uintptr(0x20000000 + 0x00030000 - 4))) = RESET_MAGIC_VALUE + *(*uint32)(unsafe.Pointer(uintptr(0x20000000 + HSRAM_SIZE - 4))) = RESET_MAGIC_VALUE arm.SystemReset() } diff --git a/src/machine/machine_atsamd51g19.go b/src/machine/machine_atsamd51g19.go index ff4583e96..ced9fd1c1 100644 --- a/src/machine/machine_atsamd51g19.go +++ b/src/machine/machine_atsamd51g19.go @@ -6,3 +6,48 @@ // http://ww1.microchip.com/downloads/en/DeviceDoc/60001507C.pdf // package machine + +import "device/sam" + +const HSRAM_SIZE = 0x00030000 + +// InitPWM initializes the PWM interface. +func InitPWM() { + // turn on timer clocks used for PWM + sam.MCLK.APBBMASK.SetBits(sam.MCLK_APBBMASK_TCC0_ | sam.MCLK_APBBMASK_TCC1_) + sam.MCLK.APBCMASK.SetBits(sam.MCLK_APBCMASK_TCC2_) + + //use clock generator 0 + sam.GCLK.PCHCTRL[25].Set((sam.GCLK_PCHCTRL_GEN_GCLK0 << sam.GCLK_PCHCTRL_GEN_Pos) | + sam.GCLK_PCHCTRL_CHEN) + sam.GCLK.PCHCTRL[29].Set((sam.GCLK_PCHCTRL_GEN_GCLK0 << sam.GCLK_PCHCTRL_GEN_Pos) | + sam.GCLK_PCHCTRL_CHEN) +} + +// getTimer returns the timer to be used for PWM on this pin +func (pwm PWM) getTimer() *sam.TCC_Type { + switch pwm.Pin { + case PA16: + return sam.TCC1 + case PA17: + return sam.TCC1 + case PA14: + return sam.TCC2 + case PA15: + return sam.TCC2 + case PA18: + return sam.TCC1 + case PA19: + return sam.TCC1 + case PA20: + return sam.TCC0 + case PA21: + return sam.TCC0 + case PA23: + return sam.TCC0 + case PA22: + return sam.TCC0 + default: + return nil // not supported on this pin + } +} diff --git a/src/machine/machine_atsamd51j19.go b/src/machine/machine_atsamd51j19.go index 18cff65c2..4ee929407 100644 --- a/src/machine/machine_atsamd51j19.go +++ b/src/machine/machine_atsamd51j19.go @@ -6,3 +6,53 @@ // http://ww1.microchip.com/downloads/en/DeviceDoc/60001507C.pdf // package machine + +import "device/sam" + +const HSRAM_SIZE = 0x00030000 + +// InitPWM initializes the PWM interface. +func InitPWM() { + // turn on timer clocks used for PWM + sam.MCLK.APBBMASK.SetBits(sam.MCLK_APBBMASK_TCC0_ | sam.MCLK_APBBMASK_TCC1_) + sam.MCLK.APBCMASK.SetBits(sam.MCLK_APBCMASK_TCC2_) + sam.MCLK.APBDMASK.SetBits(sam.MCLK_APBDMASK_TCC4_) + + //use clock generator 0 + sam.GCLK.PCHCTRL[25].Set((sam.GCLK_PCHCTRL_GEN_GCLK0 << sam.GCLK_PCHCTRL_GEN_Pos) | + sam.GCLK_PCHCTRL_CHEN) + sam.GCLK.PCHCTRL[29].Set((sam.GCLK_PCHCTRL_GEN_GCLK0 << sam.GCLK_PCHCTRL_GEN_Pos) | + sam.GCLK_PCHCTRL_CHEN) + sam.GCLK.PCHCTRL[38].Set((sam.GCLK_PCHCTRL_GEN_GCLK0 << sam.GCLK_PCHCTRL_GEN_Pos) | + sam.GCLK_PCHCTRL_CHEN) +} + +// getTimer returns the timer to be used for PWM on this pin +func (pwm PWM) getTimer() *sam.TCC_Type { + switch pwm.Pin { + case PA16: + return sam.TCC1 + case PA17: + return sam.TCC1 + case PA14: + return sam.TCC2 + case PA15: + return sam.TCC2 + case PA18: + return sam.TCC1 + case PA19: + return sam.TCC1 + case PA20: + return sam.TCC0 + case PA21: + return sam.TCC0 + case PA23: + return sam.TCC0 + case PA22: + return sam.TCC0 + case PB31: + return sam.TCC4 + default: + return nil // not supported on this pin + } +} diff --git a/src/machine/machine_atsamd51j20.go b/src/machine/machine_atsamd51j20.go new file mode 100644 index 000000000..484db6d54 --- /dev/null +++ b/src/machine/machine_atsamd51j20.go @@ -0,0 +1,58 @@ +// +build sam,atsamd51,atsamd51j20 + +// Peripheral abstraction layer for the atsamd51. +// +// Datasheet: +// http://ww1.microchip.com/downloads/en/DeviceDoc/60001507C.pdf +// +package machine + +import "device/sam" + +const HSRAM_SIZE = 0x00040000 + +// InitPWM initializes the PWM interface. +func InitPWM() { + // turn on timer clocks used for PWM + sam.MCLK.APBBMASK.SetBits(sam.MCLK_APBBMASK_TCC0_ | sam.MCLK_APBBMASK_TCC1_) + sam.MCLK.APBCMASK.SetBits(sam.MCLK_APBCMASK_TCC2_) + sam.MCLK.APBDMASK.SetBits(sam.MCLK_APBDMASK_TCC4_) + + //use clock generator 0 + sam.GCLK.PCHCTRL[25].Set((sam.GCLK_PCHCTRL_GEN_GCLK0 << sam.GCLK_PCHCTRL_GEN_Pos) | + sam.GCLK_PCHCTRL_CHEN) + sam.GCLK.PCHCTRL[29].Set((sam.GCLK_PCHCTRL_GEN_GCLK0 << sam.GCLK_PCHCTRL_GEN_Pos) | + sam.GCLK_PCHCTRL_CHEN) + sam.GCLK.PCHCTRL[38].Set((sam.GCLK_PCHCTRL_GEN_GCLK0 << sam.GCLK_PCHCTRL_GEN_Pos) | + sam.GCLK_PCHCTRL_CHEN) +} + +// getTimer returns the timer to be used for PWM on this pin +func (pwm PWM) getTimer() *sam.TCC_Type { + switch pwm.Pin { + case PA16: + return sam.TCC1 + case PA17: + return sam.TCC1 + case PA14: + return sam.TCC2 + case PA15: + return sam.TCC2 + case PA18: + return sam.TCC1 + case PA19: + return sam.TCC1 + case PA20: + return sam.TCC0 + case PA21: + return sam.TCC0 + case PA23: + return sam.TCC0 + case PA22: + return sam.TCC0 + case PB31: + return sam.TCC4 + default: + return nil // not supported on this pin + } +} diff --git a/src/runtime/runtime_atsamd51j20.go b/src/runtime/runtime_atsamd51j20.go new file mode 100644 index 000000000..84655ef59 --- /dev/null +++ b/src/runtime/runtime_atsamd51j20.go @@ -0,0 +1,43 @@ +// +build sam,atsamd51,atsamd51j20 + +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[7].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[3].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[8].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[23].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[24].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[34].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[35].Set((sam.GCLK_PCHCTRL_GEN_GCLK1 << sam.GCLK_PCHCTRL_GEN_Pos) | + sam.GCLK_PCHCTRL_CHEN) +} diff --git a/targets/atsamd51j20a.json b/targets/atsamd51j20a.json new file mode 100644 index 000000000..cab3a624a --- /dev/null +++ b/targets/atsamd51j20a.json @@ -0,0 +1,13 @@ +{ + "inherits": ["cortex-m"], + "llvm-target": "armv7em-none-eabi", + "build-tags": ["sam", "atsamd51", "atsamd51j20", "atsamd51j20a"], + "cflags": [ + "--target=armv7em-none-eabi", + "-Qunused-arguments" + ], + "linkerscript": "targets/atsamd51.ld", + "extra-files": [ + "src/device/sam/atsamd51j20a.s" + ] +} diff --git a/targets/pyportal.json b/targets/pyportal.json new file mode 100644 index 000000000..e03efcb6d --- /dev/null +++ b/targets/pyportal.json @@ -0,0 +1,8 @@ +{ + "inherits": ["atsamd51j20a"], + "build-tags": ["pyportal"], + "flash-1200-bps-reset": "true", + "flash-method": "msd", + "msd-volume-name": "PORTALBOOT", + "msd-firmware-name": "firmware.uf2" +} |