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

     1  //go:build stm32 && stm32f7x2
     2  
     3  package runtime
     4  
     5  import (
     6  	"device/stm32"
     7  	"machine"
     8  )
     9  
    10  /*
    11  clock settings
    12  
    13  	+-------------+--------+
    14  	| HSE         | 8mhz   |
    15  	| SYSCLK      | 216mhz |
    16  	| HCLK        | 216mhz |
    17  	| APB1(PCLK1) | 27mhz  |
    18  	| APB2(PCLK2) | 108mhz |
    19  	+-------------+--------+
    20  */
    21  const (
    22  	HSE_STARTUP_TIMEOUT = 0x0500
    23  	PLL_M               = 4
    24  	PLL_N               = 216
    25  	PLL_P               = 2
    26  	PLL_Q               = 2
    27  )
    28  
    29  func init() {
    30  	initCLK()
    31  
    32  	machine.InitSerial()
    33  
    34  	initTickTimer(&machine.TIM3)
    35  }
    36  
    37  func putchar(c byte) {
    38  	machine.Serial.WriteByte(c)
    39  }
    40  
    41  func getchar() byte {
    42  	for machine.Serial.Buffered() == 0 {
    43  		Gosched()
    44  	}
    45  	v, _ := machine.Serial.ReadByte()
    46  	return v
    47  }
    48  
    49  func buffered() int {
    50  	return machine.Serial.Buffered()
    51  }
    52  
    53  func initCLK() {
    54  	// PWR_CLK_ENABLE
    55  	stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_PWREN)
    56  	_ = stm32.RCC.APB1ENR.Get()
    57  
    58  	// PWR_VOLTAGESCALING_CONFIG
    59  	stm32.PWR.CR1.ReplaceBits(0x3<<stm32.PWR_CR1_VOS_Pos, stm32.PWR_CR1_VOS_Msk, 0)
    60  	_ = stm32.PWR.CR1.Get()
    61  
    62  	// Initialize the High-Speed External Oscillator
    63  	initOsc()
    64  
    65  	// Set flash wait states (min 7 latency units) based on clock
    66  	if (stm32.FLASH.ACR.Get() & stm32.FLASH_ACR_LATENCY_Msk) < 7 {
    67  		stm32.FLASH.ACR.ReplaceBits(7, stm32.FLASH_ACR_LATENCY_Msk, 0)
    68  	}
    69  
    70  	// HCLK (0x1C00 = DIV_16, 0x0 = RCC_SYSCLK_DIV1) - ensure timers remain
    71  	// within spec as the SYSCLK source changes.
    72  	stm32.RCC.CFGR.ReplaceBits(0x00001C00, stm32.RCC_CFGR_PPRE1_Msk, 0)
    73  	stm32.RCC.CFGR.ReplaceBits(0x00001C00<<3, stm32.RCC_CFGR_PPRE2_Msk, 0)
    74  	stm32.RCC.CFGR.ReplaceBits(0, stm32.RCC_CFGR_HPRE_Msk, 0)
    75  
    76  	// Set SYSCLK source and wait
    77  	// (2 = PLLCLK, 3 = RCC_CFGR_SW mask, 3 << 3 = RCC_CFGR_SWS mask)
    78  	stm32.RCC.CFGR.ReplaceBits(2, 3, 0)
    79  	for stm32.RCC.CFGR.Get()&(3<<2) != (2 << 2) {
    80  	}
    81  
    82  	// Set flash wait states (max 7 latency units) based on clock
    83  	if (stm32.FLASH.ACR.Get() & stm32.FLASH_ACR_LATENCY_Msk) > 7 {
    84  		stm32.FLASH.ACR.ReplaceBits(7, stm32.FLASH_ACR_LATENCY_Msk, 0)
    85  	}
    86  
    87  	// Set APB1 and APB2 clocks (0x1800 = DIV8, 0x1000 = DIV2)
    88  	stm32.RCC.CFGR.ReplaceBits(0x1800, stm32.RCC_CFGR_PPRE1_Msk, 0)
    89  	stm32.RCC.CFGR.ReplaceBits(0x1000<<3, stm32.RCC_CFGR_PPRE2_Msk, 0)
    90  }
    91  
    92  func initOsc() {
    93  	// Enable HSE, wait until ready
    94  	stm32.RCC.CR.SetBits(stm32.RCC_CR_HSEON)
    95  	for !stm32.RCC.CR.HasBits(stm32.RCC_CR_HSERDY) {
    96  	}
    97  
    98  	// Disable the PLL, wait until disabled
    99  	stm32.RCC.CR.ClearBits(stm32.RCC_CR_PLLON)
   100  	for stm32.RCC.CR.HasBits(stm32.RCC_CR_PLLRDY) {
   101  	}
   102  
   103  	// Configure the PLL
   104  	stm32.RCC.PLLCFGR.Set(0x20000000 |
   105  		(1 << stm32.RCC_PLLCFGR_PLLSRC_Pos) | // 1 = HSE
   106  		PLL_M |
   107  		(PLL_N << stm32.RCC_PLLCFGR_PLLN_Pos) |
   108  		(((PLL_P >> 1) - 1) << stm32.RCC_PLLCFGR_PLLP_Pos) |
   109  		(PLL_Q << stm32.RCC_PLLCFGR_PLLQ_Pos))
   110  
   111  	// Enable the PLL, wait until ready
   112  	stm32.RCC.CR.SetBits(stm32.RCC_CR_PLLON)
   113  	for !stm32.RCC.CR.HasBits(stm32.RCC_CR_PLLRDY) {
   114  	}
   115  }