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

     1  //go:build stm32l0
     2  
     3  package runtime
     4  
     5  import (
     6  	"device/stm32"
     7  	"machine"
     8  )
     9  
    10  const (
    11  	RCC_SYSCLK_DIV1 = 0 // Needs SVD update (should be stm32.RCC_SYSCLK_DIV1)
    12  )
    13  
    14  func putchar(c byte) {
    15  	machine.Serial.WriteByte(c)
    16  }
    17  
    18  func getchar() byte {
    19  	for machine.Serial.Buffered() == 0 {
    20  		Gosched()
    21  	}
    22  	v, _ := machine.Serial.ReadByte()
    23  	return v
    24  }
    25  
    26  func buffered() int {
    27  	return machine.Serial.Buffered()
    28  }
    29  
    30  func initCLK() {
    31  	// Set Power Regulator to enable max performance (1.8V)
    32  	stm32.PWR.CR.ReplaceBits(1<<stm32.PWR_CR_VOS_Pos, stm32.PWR_CR_VOS_Msk, 0)
    33  
    34  	// Calibration (default 0x10)
    35  	stm32.RCC.ICSCR.ReplaceBits(0x10<<stm32.RCC_ICSCR_HSI16TRIM_Pos, stm32.RCC_ICSCR_HSI16TRIM_Msk, 0)
    36  
    37  	// Enable the HSI16 oscillator, since the L0 series boots to the MSI one.
    38  	stm32.RCC.CR.ReplaceBits(stm32.RCC_CR_HSI16ON, stm32.RCC_CR_HSI16ON_Msk|stm32.RCC_CR_HSI16DIVEN_Msk, 0)
    39  
    40  	// Wait for HSI16 to be ready
    41  	for !stm32.RCC.CR.HasBits(stm32.RCC_CR_HSI16RDYF) {
    42  	}
    43  
    44  	// Disable PLL
    45  	stm32.RCC.CR.ClearBits(stm32.RCC_CR_PLLON)
    46  
    47  	// Wait for PLL to be disabled
    48  	for stm32.RCC.CR.HasBits(stm32.RCC_CR_PLLRDY) {
    49  	}
    50  
    51  	// Configure the PLL to use HSI16 with a PLLDIV of 2 and PLLMUL of 4.
    52  	stm32.RCC.CFGR.ReplaceBits(
    53  		(stm32.RCC_CFGR_PLLSRC_HSI16<<stm32.RCC_CFGR_PLLSRC_Pos)|
    54  			(stm32.RCC_CFGR_PLLMUL_Mul4<<stm32.RCC_CFGR_PLLMUL_Pos)|
    55  			(stm32.RCC_CFGR_PLLDIV_Div2<<stm32.RCC_CFGR_PLLDIV_Pos),
    56  		stm32.RCC_CFGR_PLLSRC_Msk|
    57  			stm32.RCC_CFGR_PLLMUL_Msk|
    58  			stm32.RCC_CFGR_PLLDIV_Msk,
    59  		0)
    60  
    61  	// Enable PLL
    62  	stm32.RCC.CR.SetBits(stm32.RCC_CR_PLLON)
    63  
    64  	// Wait for PLL to be ready
    65  	for !stm32.RCC.CR.HasBits(stm32.RCC_CR_PLLRDY) {
    66  	}
    67  
    68  	// Adjust flash latency
    69  	if FlashLatency > getFlashLatency() {
    70  		setFlashLatency(FlashLatency)
    71  		for getFlashLatency() != FlashLatency {
    72  		}
    73  	}
    74  
    75  	// HCLK
    76  	stm32.RCC.CFGR.ReplaceBits(RCC_SYSCLK_DIV1, stm32.RCC_CFGR_HPRE_Msk, 0)
    77  
    78  	// Use PLL As System clock
    79  	stm32.RCC.CFGR.ReplaceBits(stm32.RCC_CFGR_SWS_PLL, stm32.RCC_CFGR_SW_Msk, 0)
    80  	for stm32.RCC.CFGR.Get()&stm32.RCC_CFGR_SW_Msk != stm32.RCC_CFGR_SWS_PLL {
    81  	}
    82  
    83  	// Set prescalers so half system clock (PCLKx = HCLK/2)
    84  	stm32.RCC.CFGR.SetBits(stm32.RCC_CFGR_PPRE1_Div2 << stm32.RCC_CFGR_PPRE1_Pos)
    85  	stm32.RCC.CFGR.SetBits(stm32.RCC_CFGR_PPRE2_Div2 << stm32.RCC_CFGR_PPRE2_Pos)
    86  }
    87  
    88  func getFlashLatency() uint32 {
    89  	return stm32.FLASH.ACR.Get() & stm32.Flash_ACR_LATENCY_Msk
    90  }
    91  
    92  func setFlashLatency(l uint32) {
    93  	stm32.FLASH.ACR.ReplaceBits(l, stm32.Flash_ACR_LATENCY_Msk, 0)
    94  }