|
1 |
| -//go:build rp2040 |
| 1 | +//go:build rp2040 || rp2350 |
2 | 2 |
|
3 | 3 | package machine
|
4 | 4 |
|
5 | 5 | import (
|
6 | 6 | "device/rp"
|
| 7 | + "runtime/interrupt" |
7 | 8 | "runtime/volatile"
|
8 | 9 | "unsafe"
|
9 | 10 | )
|
10 | 11 |
|
11 | 12 | const deviceName = rp.Device
|
12 | 13 |
|
| 14 | +const ( |
| 15 | + // Number of spin locks available |
| 16 | + // Note: On RP2350, most spinlocks are unusable due to Errata 2 |
| 17 | + _NUMSPINLOCKS = 32 |
| 18 | + _PICO_SPINLOCK_ID_IRQ = 9 |
| 19 | +) |
| 20 | + |
| 21 | +// UART on the RP2040 |
| 22 | +var ( |
| 23 | + UART0 = &_UART0 |
| 24 | + _UART0 = UART{ |
| 25 | + Buffer: NewRingBuffer(), |
| 26 | + Bus: rp.UART0, |
| 27 | + } |
| 28 | + |
| 29 | + UART1 = &_UART1 |
| 30 | + _UART1 = UART{ |
| 31 | + Buffer: NewRingBuffer(), |
| 32 | + Bus: rp.UART1, |
| 33 | + } |
| 34 | +) |
| 35 | + |
| 36 | +func init() { |
| 37 | + UART0.Interrupt = interrupt.New(rp.IRQ_UART0_IRQ, _UART0.handleInterrupt) |
| 38 | + UART1.Interrupt = interrupt.New(rp.IRQ_UART1_IRQ, _UART1.handleInterrupt) |
| 39 | +} |
| 40 | + |
13 | 41 | //go:linkname machineInit runtime.machineInit
|
14 | 42 | func machineInit() {
|
15 | 43 | // Reset all peripherals to put system into a known state,
|
16 | 44 | // except for QSPI pads and the XIP IO bank, as this is fatal if running from flash
|
17 | 45 | // and the PLLs, as this is fatal if clock muxing has not been reset on this boot
|
18 | 46 | // and USB, syscfg, as this disturbs USB-to-SWD on core 1
|
19 |
| - bits := ^uint32(rp.RESETS_RESET_IO_QSPI | |
20 |
| - rp.RESETS_RESET_PADS_QSPI | |
21 |
| - rp.RESETS_RESET_PLL_USB | |
22 |
| - rp.RESETS_RESET_USBCTRL | |
23 |
| - rp.RESETS_RESET_SYSCFG | |
24 |
| - rp.RESETS_RESET_PLL_SYS) |
| 47 | + bits := ^uint32(initDontReset) |
25 | 48 | resetBlock(bits)
|
26 | 49 |
|
27 | 50 | // Remove reset from peripherals which are clocked only by clkSys and
|
28 | 51 | // clkRef. Other peripherals stay in reset until we've configured clocks.
|
29 |
| - bits = ^uint32(rp.RESETS_RESET_ADC | |
30 |
| - rp.RESETS_RESET_RTC | |
31 |
| - rp.RESETS_RESET_SPI0 | |
32 |
| - rp.RESETS_RESET_SPI1 | |
33 |
| - rp.RESETS_RESET_UART0 | |
34 |
| - rp.RESETS_RESET_UART1 | |
35 |
| - rp.RESETS_RESET_USBCTRL) |
| 52 | + bits = ^uint32(initUnreset) |
36 | 53 | unresetBlockWait(bits)
|
37 | 54 |
|
38 | 55 | clocks.init()
|
@@ -94,4 +111,25 @@ const (
|
94 | 111 | )
|
95 | 112 |
|
96 | 113 | // DMA channels usable on the RP2040.
|
97 |
| -var dmaChannels = (*[12]dmaChannel)(unsafe.Pointer(rp.DMA)) |
| 114 | +var dmaChannels = (*[12 + 4*rp2350ExtraReg]dmaChannel)(unsafe.Pointer(rp.DMA)) |
| 115 | + |
| 116 | +//go:inline |
| 117 | +func boolToBit(a bool) uint32 { |
| 118 | + if a { |
| 119 | + return 1 |
| 120 | + } |
| 121 | + return 0 |
| 122 | +} |
| 123 | + |
| 124 | +//go:inline |
| 125 | +func u32max(a, b uint32) uint32 { |
| 126 | + if a > b { |
| 127 | + return a |
| 128 | + } |
| 129 | + return b |
| 130 | +} |
| 131 | + |
| 132 | +//go:inline |
| 133 | +func isReservedI2CAddr(addr uint8) bool { |
| 134 | + return (addr&0x78) == 0 || (addr&0x78) == 0x78 |
| 135 | +} |
0 commit comments