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

     1  //go:build stm32 && stm32l4
     2  
     3  package runtime
     4  
     5  import (
     6  	"device/stm32"
     7  	"machine"
     8  )
     9  
    10  const (
    11  	PWR_CR1_VOS_0                = 1 << stm32.PWR_CR1_VOS_Pos
    12  	PWR_CR1_VOS_1                = 2 << stm32.PWR_CR1_VOS_Pos
    13  	PWR_REGULATOR_VOLTAGE_SCALE1 = PWR_CR1_VOS_0
    14  	PWR_REGULATOR_VOLTAGE_SCALE2 = PWR_CR1_VOS_1
    15  
    16  	FLASH_LATENCY_0 = 0
    17  	FLASH_LATENCY_1 = 1
    18  	FLASH_LATENCY_2 = 2
    19  	FLASH_LATENCY_3 = 3
    20  	FLASH_LATENCY_4 = 4
    21  
    22  	RCC_PLLP_DIV2 = 2
    23  	RCC_PLLP_DIV7 = 7
    24  	RCC_PLLQ_DIV2 = 2
    25  	RCC_PLLR_DIV2 = 2
    26  
    27  	RCC_CFGR_SWS_MSI = 0x0
    28  	RCC_CFGR_SWS_PLL = 0xC
    29  
    30  	RCC_PLLSOURCE_MSI = 1
    31  
    32  	RCC_PLL_SYSCLK = stm32.RCC_PLLCFGR_PLLREN
    33  )
    34  
    35  type arrtype = uint32
    36  
    37  func init() {
    38  	initCLK()
    39  
    40  	machine.InitSerial()
    41  
    42  	initTickTimer(&machine.TIM15)
    43  }
    44  
    45  func putchar(c byte) {
    46  	machine.Serial.WriteByte(c)
    47  }
    48  
    49  func getchar() byte {
    50  	for machine.Serial.Buffered() == 0 {
    51  		Gosched()
    52  	}
    53  	v, _ := machine.Serial.ReadByte()
    54  	return v
    55  }
    56  
    57  func buffered() int {
    58  	return machine.Serial.Buffered()
    59  }
    60  
    61  func initCLK() {
    62  	// PWR_CLK_ENABLE
    63  	stm32.RCC.APB1ENR1.SetBits(stm32.RCC_APB1ENR1_PWREN)
    64  	_ = stm32.RCC.APB1ENR1.Get()
    65  
    66  	// Disable Backup domain protection
    67  	if !stm32.PWR.CR1.HasBits(stm32.PWR_CR1_DBP) {
    68  		stm32.PWR.CR1.SetBits(stm32.PWR_CR1_DBP)
    69  		for !stm32.PWR.CR1.HasBits(stm32.PWR_CR1_DBP) {
    70  		}
    71  	}
    72  
    73  	// Set LSE Drive to LOW
    74  	stm32.RCC.BDCR.ReplaceBits(0, stm32.RCC_BDCR_LSEDRV_Msk, 0)
    75  
    76  	// Initialize the High-Speed External Oscillator
    77  	initOsc()
    78  
    79  	// PWR_VOLTAGESCALING_CONFIG
    80  	stm32.PWR.CR1.ReplaceBits(0, stm32.PWR_CR1_VOS_Msk, 0)
    81  	_ = stm32.PWR.CR1.Get()
    82  
    83  	// Set flash wait states (min 5 latency units) based on clock
    84  	if (stm32.FLASH.ACR.Get() & 0xF) < 5 {
    85  		stm32.FLASH.ACR.ReplaceBits(5, 0xF, 0)
    86  	}
    87  
    88  	// Ensure HCLK does not exceed max during transition
    89  	stm32.RCC.CFGR.ReplaceBits(8<<stm32.RCC_CFGR_HPRE_Pos, stm32.RCC_CFGR_HPRE_Msk, 0)
    90  
    91  	// Set SYSCLK source and wait
    92  	// (3 = RCC_SYSCLKSOURCE_PLLCLK, 2=RCC_CFGR_SWS_Pos)
    93  	stm32.RCC.CFGR.ReplaceBits(3, stm32.RCC_CFGR_SW_Msk, 0)
    94  	for stm32.RCC.CFGR.Get()&(3<<2) != (3 << 2) {
    95  	}
    96  
    97  	// Set HCLK
    98  	// (0 = RCC_SYSCLKSOURCE_PLLCLK)
    99  	stm32.RCC.CFGR.ReplaceBits(0, stm32.RCC_CFGR_HPRE_Msk, 0)
   100  
   101  	// Set flash wait states (max 5 latency units) based on clock
   102  	if (stm32.FLASH.ACR.Get() & 0xF) > 5 {
   103  		stm32.FLASH.ACR.ReplaceBits(5, 0xF, 0)
   104  	}
   105  
   106  	// Set APB1 and APB2 clocks (0 = DIV1)
   107  	stm32.RCC.CFGR.ReplaceBits(0, stm32.RCC_CFGR_PPRE1_Msk, 0)
   108  	stm32.RCC.CFGR.ReplaceBits(0, stm32.RCC_CFGR_PPRE2_Msk, 0)
   109  }
   110  
   111  func initOsc() {
   112  	sysclkSource := stm32.RCC.CFGR.Get() & stm32.RCC_CFGR_SWS_Msk
   113  	pllConfig := stm32.RCC.PLLCFGR.Get() & stm32.RCC_PLLCFGR_PLLSRC_Msk
   114  
   115  	// Enable MSI, adjusting flash latency
   116  	if sysclkSource == RCC_CFGR_SWS_MSI ||
   117  		(sysclkSource == RCC_CFGR_SWS_PLL && pllConfig == RCC_PLLSOURCE_MSI) {
   118  		if MSIRANGE > getMSIRange() {
   119  			setFlashLatencyFromMSIRange(MSIRANGE)
   120  
   121  			setMSIFreq(MSIRANGE, 0)
   122  		} else {
   123  			setMSIFreq(MSIRANGE, 0)
   124  
   125  			if sysclkSource == RCC_CFGR_SWS_MSI {
   126  				setFlashLatencyFromMSIRange(MSIRANGE)
   127  			}
   128  		}
   129  	} else {
   130  		stm32.RCC.CR.SetBits(stm32.RCC_CR_MSION)
   131  		for !stm32.RCC.CR.HasBits(stm32.RCC_CR_MSIRDY) {
   132  		}
   133  
   134  		setMSIFreq(MSIRANGE, 0)
   135  	}
   136  
   137  	// Enable LSE, wait until ready
   138  	stm32.RCC.BDCR.SetBits(stm32.RCC_BDCR_LSEON)
   139  	for !stm32.RCC.BDCR.HasBits(stm32.RCC_BDCR_LSEON) {
   140  	}
   141  
   142  	// Disable the PLL, wait until disabled
   143  	stm32.RCC.CR.ClearBits(stm32.RCC_CR_PLLON)
   144  	for stm32.RCC.CR.HasBits(stm32.RCC_CR_PLLRDY) {
   145  	}
   146  
   147  	// Configure the PLL
   148  	stm32.RCC.PLLCFGR.ReplaceBits(
   149  		(1)| // 1 = RCC_PLLSOURCE_MSI
   150  			(PLL_M-1)<<stm32.RCC_PLLCFGR_PLLM_Pos|
   151  			(PLL_N<<stm32.RCC_PLLCFGR_PLLN_Pos)|
   152  			(((PLL_Q>>1)-1)<<stm32.RCC_PLLCFGR_PLLQ_Pos)|
   153  			(((PLL_R>>1)-1)<<stm32.RCC_PLLCFGR_PLLR_Pos)|
   154  			(PLL_P<<stm32.RCC_PLLCFGR_PLLP_Pos),
   155  		stm32.RCC_PLLCFGR_PLLSRC_Msk|stm32.RCC_PLLCFGR_PLLM_Msk|
   156  			stm32.RCC_PLLCFGR_PLLN_Msk|stm32.RCC_PLLCFGR_PLLP_Msk|
   157  			stm32.RCC_PLLCFGR_PLLR_Msk|stm32.RCC_PLLCFGR_PLLP_Msk,
   158  		0)
   159  
   160  	// Enable the PLL and PLL System Clock Output, wait until ready
   161  	stm32.RCC.CR.SetBits(stm32.RCC_CR_PLLON)
   162  	stm32.RCC.PLLCFGR.SetBits(stm32.RCC_PLLCFGR_PLLREN) // = RCC_PLL_SYSCLK
   163  	for !stm32.RCC.CR.HasBits(stm32.RCC_CR_PLLRDY) {
   164  	}
   165  
   166  	// Enable system clock output
   167  	stm32.RCC.PLLCFGR.SetBits(RCC_PLL_SYSCLK)
   168  }
   169  
   170  func getMSIRange() uint32 {
   171  	if stm32.RCC.CR.HasBits(stm32.RCC_CR_MSIRGSEL) {
   172  		return (stm32.RCC.CR.Get() & stm32.RCC_CR_MSIRANGE_Msk) >> stm32.RCC_CR_MSIRANGE_Pos
   173  	}
   174  
   175  	return (stm32.RCC.CSR.Get() & stm32.RCC_CSR_MSISRANGE_Msk) >> stm32.RCC_CSR_MSISRANGE_Pos
   176  }
   177  
   178  func setMSIFreq(r uint32, calibration uint32) {
   179  	stm32.RCC.CR.SetBits(stm32.RCC_CR_MSIRGSEL)
   180  	stm32.RCC.CR.ReplaceBits(r<<stm32.RCC_CR_MSIRANGE_Pos, stm32.RCC_CR_MSIRANGE_Msk, 0)
   181  
   182  	stm32.RCC.ICSCR.ReplaceBits(calibration<<stm32.RCC_ICSCR_MSITRIM_Pos, stm32.RCC_ICSCR_MSITRIM_Msk, 0)
   183  }
   184  
   185  func setFlashLatencyFromMSIRange(r uint32) {
   186  	var vos uint32
   187  	if pwrIsClkEnabled() {
   188  		vos = pwrExGetVoltageRange()
   189  	} else {
   190  		pwrClkEnable()
   191  		vos = pwrExGetVoltageRange()
   192  		pwrClkDisable()
   193  	}
   194  
   195  	latency := uint32(FLASH_LATENCY_0)
   196  	if vos == PWR_REGULATOR_VOLTAGE_SCALE1 {
   197  		if r > stm32.RCC_CR_MSIRANGE_Range16M {
   198  			if r > stm32.RCC_CR_MSIRANGE_Range32M {
   199  				latency = FLASH_LATENCY_2
   200  			} else {
   201  				latency = FLASH_LATENCY_1
   202  			}
   203  		}
   204  	} else if r > stm32.RCC_CR_MSIRANGE_Range16M {
   205  		latency = FLASH_LATENCY_3
   206  	} else {
   207  		if r == stm32.RCC_CR_MSIRANGE_Range16M {
   208  			latency = FLASH_LATENCY_2
   209  		} else if r == stm32.RCC_CR_MSIRANGE_Range8M {
   210  			latency = FLASH_LATENCY_1
   211  		}
   212  	}
   213  
   214  	stm32.FLASH.ACR.ReplaceBits(latency, stm32.Flash_ACR_LATENCY_Msk, 0)
   215  }
   216  
   217  func pwrIsClkEnabled() bool {
   218  	return stm32.RCC.APB1ENR1.HasBits(stm32.RCC_APB1ENR1_PWREN)
   219  }
   220  
   221  func pwrClkEnable() {
   222  	stm32.RCC.APB1ENR1.SetBits(stm32.RCC_APB1ENR1_PWREN)
   223  }
   224  func pwrClkDisable() {
   225  	stm32.RCC.APB1ENR1.ClearBits(stm32.RCC_APB1ENR1_PWREN)
   226  }
   227  
   228  func pwrExGetVoltageRange() uint32 {
   229  	return stm32.PWR.CR1.Get() & stm32.PWR_CR1_VOS_Msk
   230  }