
This can be very useful for some purposes: * It makes it possible to disable the UART in cases where it is not needed or needs to be disabled to conserve power. * It makes it possible to disable the serial output to reduce code size, which may be important for some chips. Sometimes, a few kB can be saved this way. * It makes it possible to override the default, for example you might want to use an actual UART to debug the USB-CDC implementation. It also lowers the dependency on having machine.Serial defined, which is often not defined when targeting a chip. Eventually, we might want to make it possible to write `-target=nrf52` or `-target=atmega328p` for example to target the chip itself with no board specific assumptions. The defaults don't change. I checked this by running `make smoketest` before and after and comparing the results.
116 строки
2,3 КиБ
Go
116 строки
2,3 КиБ
Go
// +build rp2040
|
|
|
|
package machine
|
|
|
|
import (
|
|
"device/rp"
|
|
"runtime/interrupt"
|
|
)
|
|
|
|
const (
|
|
// GPIO pins
|
|
GPIO0 Pin = 0
|
|
GPIO1 Pin = 1
|
|
GPIO2 Pin = 2
|
|
GPIO3 Pin = 3
|
|
GPIO4 Pin = 4
|
|
GPIO5 Pin = 5
|
|
GPIO6 Pin = 6
|
|
GPIO7 Pin = 7
|
|
GPIO8 Pin = 8
|
|
GPIO9 Pin = 9
|
|
GPIO10 Pin = 10
|
|
GPIO11 Pin = 11
|
|
GPIO12 Pin = 12
|
|
GPIO13 Pin = 13
|
|
GPIO14 Pin = 14
|
|
GPIO15 Pin = 15
|
|
GPIO16 Pin = 16
|
|
GPIO17 Pin = 17
|
|
GPIO18 Pin = 18
|
|
GPIO19 Pin = 19
|
|
GPIO20 Pin = 20
|
|
GPIO21 Pin = 21
|
|
GPIO22 Pin = 22
|
|
GPIO23 Pin = 23
|
|
GPIO24 Pin = 24
|
|
GPIO25 Pin = 25
|
|
GPIO26 Pin = 26
|
|
GPIO27 Pin = 27
|
|
GPIO28 Pin = 28
|
|
GPIO29 Pin = 29
|
|
|
|
// Analog pins
|
|
ADC0 Pin = GPIO26
|
|
ADC1 Pin = GPIO27
|
|
ADC2 Pin = GPIO28
|
|
ADC3 Pin = GPIO29
|
|
)
|
|
|
|
//go:linkname machineInit runtime.machineInit
|
|
func machineInit() {
|
|
// Reset all peripherals to put system into a known state,
|
|
// except for QSPI pads and the XIP IO bank, as this is fatal if running from flash
|
|
// and the PLLs, as this is fatal if clock muxing has not been reset on this boot
|
|
// and USB, syscfg, as this disturbs USB-to-SWD on core 1
|
|
bits := ^uint32(rp.RESETS_RESET_IO_QSPI |
|
|
rp.RESETS_RESET_PADS_QSPI |
|
|
rp.RESETS_RESET_PLL_USB |
|
|
rp.RESETS_RESET_USBCTRL |
|
|
rp.RESETS_RESET_SYSCFG |
|
|
rp.RESETS_RESET_PLL_SYS)
|
|
resetBlock(bits)
|
|
|
|
// Remove reset from peripherals which are clocked only by clkSys and
|
|
// clkRef. Other peripherals stay in reset until we've configured clocks.
|
|
bits = ^uint32(rp.RESETS_RESET_ADC |
|
|
rp.RESETS_RESET_RTC |
|
|
rp.RESETS_RESET_SPI0 |
|
|
rp.RESETS_RESET_SPI1 |
|
|
rp.RESETS_RESET_UART0 |
|
|
rp.RESETS_RESET_UART1 |
|
|
rp.RESETS_RESET_USBCTRL)
|
|
unresetBlockWait(bits)
|
|
|
|
clocks.init()
|
|
|
|
// Peripheral clocks should now all be running
|
|
unresetBlockWait(RESETS_RESET_Msk)
|
|
}
|
|
|
|
//go:linkname ticks runtime.machineTicks
|
|
func ticks() uint64 {
|
|
return timer.timeElapsed()
|
|
}
|
|
|
|
// UART pins
|
|
const (
|
|
UART_TX_PIN = UART0_TX_PIN
|
|
UART_RX_PIN = UART0_RX_PIN
|
|
UART0_TX_PIN = GPIO0
|
|
UART0_RX_PIN = GPIO1
|
|
UART1_TX_PIN = GPIO8
|
|
UART1_RX_PIN = GPIO9
|
|
)
|
|
|
|
// UART on the RP2040
|
|
var (
|
|
UART0 = &_UART0
|
|
_UART0 = UART{
|
|
Buffer: NewRingBuffer(),
|
|
Bus: rp.UART0,
|
|
}
|
|
|
|
UART1 = &_UART1
|
|
_UART1 = UART{
|
|
Buffer: NewRingBuffer(),
|
|
Bus: rp.UART1,
|
|
}
|
|
)
|
|
|
|
var DefaultUART = UART0
|
|
|
|
func init() {
|
|
UART0.Interrupt = interrupt.New(rp.IRQ_UART0_IRQ, _UART0.handleInterrupt)
|
|
UART1.Interrupt = interrupt.New(rp.IRQ_UART1_IRQ, _UART1.handleInterrupt)
|
|
}
|