github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/src/machine/machine_rp2040.go (about)

     1  //go:build rp2040
     2  
     3  package machine
     4  
     5  import (
     6  	"device/rp"
     7  	"runtime/volatile"
     8  	"unsafe"
     9  )
    10  
    11  const deviceName = rp.Device
    12  
    13  //go:linkname machineInit runtime.machineInit
    14  func machineInit() {
    15  	// Reset all peripherals to put system into a known state,
    16  	// except for QSPI pads and the XIP IO bank, as this is fatal if running from flash
    17  	// and the PLLs, as this is fatal if clock muxing has not been reset on this boot
    18  	// 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)
    25  	resetBlock(bits)
    26  
    27  	// Remove reset from peripherals which are clocked only by clkSys and
    28  	// 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)
    36  	unresetBlockWait(bits)
    37  
    38  	clocks.init()
    39  
    40  	// Peripheral clocks should now all be running
    41  	unresetBlockWait(RESETS_RESET_Msk)
    42  }
    43  
    44  //go:linkname ticks runtime.machineTicks
    45  func ticks() uint64 {
    46  	return timer.timeElapsed()
    47  }
    48  
    49  //go:linkname lightSleep runtime.machineLightSleep
    50  func lightSleep(ticks uint64) {
    51  	timer.lightSleep(ticks)
    52  }
    53  
    54  // CurrentCore returns the core number the call was made from.
    55  func CurrentCore() int {
    56  	return int(rp.SIO.CPUID.Get())
    57  }
    58  
    59  // NumCores returns number of cores available on the device.
    60  func NumCores() int { return 2 }
    61  
    62  // ChipVersion returns the version of the chip. 1 is returned for B0 and B1
    63  // chip.
    64  func ChipVersion() uint8 {
    65  	const (
    66  		SYSINFO_BASE                  = 0x40000000
    67  		SYSINFO_CHIP_ID_OFFSET        = 0x00000000
    68  		SYSINFO_CHIP_ID_REVISION_BITS = 0xf0000000
    69  		SYSINFO_CHIP_ID_REVISION_LSB  = 28
    70  	)
    71  
    72  	// First register of sysinfo is chip id
    73  	chipID := *(*uint32)(unsafe.Pointer(uintptr(SYSINFO_BASE + SYSINFO_CHIP_ID_OFFSET)))
    74  	// Version 1 == B0/B1
    75  	version := (chipID & SYSINFO_CHIP_ID_REVISION_BITS) >> SYSINFO_CHIP_ID_REVISION_LSB
    76  	return uint8(version)
    77  }
    78  
    79  // Single DMA channel. See rp.DMA_Type.
    80  type dmaChannel struct {
    81  	READ_ADDR   volatile.Register32
    82  	WRITE_ADDR  volatile.Register32
    83  	TRANS_COUNT volatile.Register32
    84  	CTRL_TRIG   volatile.Register32
    85  	_           [12]volatile.Register32 // aliases
    86  }
    87  
    88  // Static assignment of DMA channels to peripherals.
    89  // Allocating them statically is good enough for now. If lots of peripherals use
    90  // DMA, these might need to be assigned at runtime.
    91  const (
    92  	spi0DMAChannel = iota
    93  	spi1DMAChannel
    94  )
    95  
    96  // DMA channels usable on the RP2040.
    97  var dmaChannels = (*[12]dmaChannel)(unsafe.Pointer(rp.DMA))