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

     1  //go:build rp2040
     2  
     3  package machine
     4  
     5  import (
     6  	"device/rp"
     7  	"runtime/volatile"
     8  	"unsafe"
     9  )
    10  
    11  // On some boards, the XOSC can take longer than usual to stabilize. On such
    12  // boards, this is needed to avoid a hard fault on boot/reset. Refer to
    13  // PICO_XOSC_STARTUP_DELAY_MULTIPLIER in the Pico SDK for additional details.
    14  const XOSC_STARTUP_DELAY_MULTIPLIER = 64
    15  
    16  type xoscType struct {
    17  	ctrl     volatile.Register32
    18  	status   volatile.Register32
    19  	dormant  volatile.Register32
    20  	startup  volatile.Register32
    21  	reserved [3]volatile.Register32
    22  	count    volatile.Register32
    23  }
    24  
    25  var xosc = (*xoscType)(unsafe.Pointer(rp.XOSC))
    26  
    27  // init initializes the crystal oscillator system.
    28  //
    29  // This function will block until the crystal oscillator has stabilised.
    30  func (osc *xoscType) init() {
    31  	// Assumes 1-15 MHz input
    32  	if xoscFreq > 15 {
    33  		panic("xosc frequency cannot be greater than 15MHz")
    34  	}
    35  	osc.ctrl.Set(rp.XOSC_CTRL_FREQ_RANGE_1_15MHZ)
    36  
    37  	// Set xosc startup delay
    38  	delay := (((xoscFreq * MHz) / 1000) + 128) / 256 * XOSC_STARTUP_DELAY_MULTIPLIER
    39  	osc.startup.Set(uint32(delay))
    40  
    41  	// Set the enable bit now that we have set freq range and startup delay
    42  	osc.ctrl.SetBits(rp.XOSC_CTRL_ENABLE_ENABLE << rp.XOSC_CTRL_ENABLE_Pos)
    43  
    44  	// Wait for xosc to be stable
    45  	for !osc.status.HasBits(rp.XOSC_STATUS_STABLE) {
    46  	}
    47  }