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

     1  //go:build stm32 && stm32l5x2
     2  
     3  package runtime
     4  
     5  import (
     6  	"device/stm32"
     7  	"machine"
     8  )
     9  
    10  /*
    11  clock settings
    12  
    13  	+-------------+-----------+
    14  	| LSE         | 32.768khz |
    15  	| SYSCLK      | 110mhz    |
    16  	| HCLK        | 110mhz    |
    17  	| APB1(PCLK1) | 110mhz    |
    18  	| APB2(PCLK2) | 110mhz    |
    19  	+-------------+-----------+
    20  */
    21  const (
    22  	HSE_STARTUP_TIMEOUT = 0x0500
    23  	PLL_M               = 1
    24  	PLL_N               = 55
    25  	PLL_P               = 7 // RCC_PLLP_DIV7
    26  	PLL_Q               = 2 // RCC_PLLQ_DIV2
    27  	PLL_R               = 2 // RCC_PLLR_DIV2
    28  )
    29  
    30  func init() {
    31  	initCLK()
    32  
    33  	machine.InitSerial()
    34  
    35  	initTickTimer(&machine.TIM16)
    36  }
    37  
    38  func putchar(c byte) {
    39  	machine.Serial.WriteByte(c)
    40  }
    41  
    42  func getchar() byte {
    43  	for machine.Serial.Buffered() == 0 {
    44  		Gosched()
    45  	}
    46  	v, _ := machine.Serial.ReadByte()
    47  	return v
    48  }
    49  
    50  func buffered() int {
    51  	return machine.Serial.Buffered()
    52  }
    53  
    54  func initCLK() {
    55  
    56  	// PWR_CLK_ENABLE
    57  	stm32.RCC.APB1ENR1.SetBits(stm32.RCC_APB1ENR1_PWREN)
    58  	_ = stm32.RCC.APB1ENR1.Get()
    59  
    60  	// PWR_VOLTAGESCALING_CONFIG
    61  	stm32.PWR.CR1.ReplaceBits(0, stm32.PWR_CR1_VOS_Msk, 0)
    62  	_ = stm32.PWR.CR1.Get()
    63  
    64  	// Initialize the High-Speed External Oscillator
    65  	initOsc()
    66  
    67  	// Set flash wait states (min 5 latency units) based on clock
    68  	if (stm32.FLASH.ACR.Get() & 0xF) < 5 {
    69  		stm32.FLASH.ACR.ReplaceBits(5, 0xF, 0)
    70  	}
    71  
    72  	// Ensure HCLK does not exceed max during transition
    73  	stm32.RCC.CFGR.ReplaceBits(8<<stm32.RCC_CFGR_HPRE_Pos, stm32.RCC_CFGR_HPRE_Msk, 0)
    74  
    75  	// Set SYSCLK source and wait
    76  	// (3 = RCC_SYSCLKSOURCE_PLLCLK, 2=RCC_CFGR_SWS_Pos)
    77  	stm32.RCC.CFGR.ReplaceBits(3, stm32.RCC_CFGR_SW_Msk, 0)
    78  	for stm32.RCC.CFGR.Get()&(3<<2) != (3 << 2) {
    79  	}
    80  
    81  	// Set HCLK
    82  	// (0 = RCC_SYSCLKSOURCE_PLLCLK)
    83  	stm32.RCC.CFGR.ReplaceBits(0, stm32.RCC_CFGR_HPRE_Msk, 0)
    84  
    85  	// Set flash wait states (max 5 latency units) based on clock
    86  	if (stm32.FLASH.ACR.Get() & 0xF) > 5 {
    87  		stm32.FLASH.ACR.ReplaceBits(5, 0xF, 0)
    88  	}
    89  
    90  	// Set APB1 and APB2 clocks (0 = DIV1)
    91  	stm32.RCC.CFGR.ReplaceBits(0, stm32.RCC_CFGR_PPRE1_Msk, 0)
    92  	stm32.RCC.CFGR.ReplaceBits(0, stm32.RCC_CFGR_PPRE2_Msk, 0)
    93  }
    94  
    95  func initOsc() {
    96  	// Enable HSI, wait until ready
    97  	stm32.RCC.CR.SetBits(stm32.RCC_CR_HSION)
    98  	for !stm32.RCC.CR.HasBits(stm32.RCC_CR_HSIRDY) {
    99  	}
   100  
   101  	// Disable Backup domain protection
   102  	if !stm32.PWR.CR1.HasBits(stm32.PWR_CR1_DBP) {
   103  		stm32.PWR.CR1.SetBits(stm32.PWR_CR1_DBP)
   104  		for !stm32.PWR.CR1.HasBits(stm32.PWR_CR1_DBP) {
   105  		}
   106  	}
   107  
   108  	// Set LSE Drive to LOW
   109  	stm32.RCC.BDCR.ReplaceBits(0, stm32.RCC_BDCR_LSEDRV_Msk, 0)
   110  
   111  	// Enable LSE, wait until ready
   112  	stm32.RCC.BDCR.SetBits(stm32.RCC_BDCR_LSEON)
   113  	for !stm32.RCC.BDCR.HasBits(stm32.RCC_BDCR_LSEON) {
   114  	}
   115  
   116  	// Ensure LSESYS disabled
   117  	stm32.RCC.BDCR.ClearBits(stm32.RCC_BDCR_LSESYSEN)
   118  	for stm32.RCC.BDCR.HasBits(stm32.RCC_BDCR_LSESYSEN) {
   119  	}
   120  
   121  	// Enable HSI48, wait until ready
   122  	stm32.RCC.CRRCR.SetBits(stm32.RCC_CRRCR_HSI48ON)
   123  	for !stm32.RCC.CRRCR.HasBits(stm32.RCC_CRRCR_HSI48ON) {
   124  	}
   125  
   126  	// Disable the PLL, wait until disabled
   127  	stm32.RCC.CR.ClearBits(stm32.RCC_CR_PLLON)
   128  	for stm32.RCC.CR.HasBits(stm32.RCC_CR_PLLRDY) {
   129  	}
   130  
   131  	// Configure the PLL
   132  	stm32.RCC.PLLCFGR.ReplaceBits(
   133  		(1)| // 1 = RCC_PLLSOURCE_MSI
   134  			(PLL_M-1)<<stm32.RCC_PLLCFGR_PLLM_Pos|
   135  			(PLL_N<<stm32.RCC_PLLCFGR_PLLN_Pos)|
   136  			(((PLL_Q>>1)-1)<<stm32.RCC_PLLCFGR_PLLQ_Pos)|
   137  			(((PLL_R>>1)-1)<<stm32.RCC_PLLCFGR_PLLR_Pos)|
   138  			(PLL_P<<stm32.RCC_PLLCFGR_PLLPDIV_Pos),
   139  		stm32.RCC_PLLCFGR_PLLSRC_Msk|stm32.RCC_PLLCFGR_PLLM_Msk|
   140  			stm32.RCC_PLLCFGR_PLLN_Msk|stm32.RCC_PLLCFGR_PLLP_Msk|
   141  			stm32.RCC_PLLCFGR_PLLR_Msk|stm32.RCC_PLLCFGR_PLLPDIV_Msk,
   142  		0)
   143  
   144  	// Enable the PLL and PLL System Clock Output, wait until ready
   145  	stm32.RCC.CR.SetBits(stm32.RCC_CR_PLLON)
   146  	stm32.RCC.PLLCFGR.SetBits(stm32.RCC_PLLCFGR_PLLREN) // = RCC_PLL_SYSCLK
   147  	for !stm32.RCC.CR.HasBits(stm32.RCC_CR_PLLRDY) {
   148  	}
   149  
   150  }