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

     1  //go:build stm32 && stm32f103
     2  
     3  package machine
     4  
     5  // Peripheral abstraction layer for the stm32.
     6  
     7  import (
     8  	"device/stm32"
     9  	"runtime/interrupt"
    10  	"runtime/volatile"
    11  	"unsafe"
    12  )
    13  
    14  func CPUFrequency() uint32 {
    15  	return 72000000
    16  }
    17  
    18  var deviceIDAddr = []uintptr{0x1FFFF7E8, 0x1FFFF7EC, 0x1FFFF7F0}
    19  
    20  // Internal use: configured speed of the APB1 and APB2 timers, this should be kept
    21  // in sync with any changes to runtime package which configures the oscillators
    22  // and clock frequencies
    23  const APB1_TIM_FREQ = 72e6 // 72MHz
    24  const APB2_TIM_FREQ = 72e6 // 72MHz
    25  
    26  const (
    27  	PinInput       PinMode = 0 // Input mode
    28  	PinOutput10MHz PinMode = 1 // Output mode, max speed 10MHz
    29  	PinOutput2MHz  PinMode = 2 // Output mode, max speed 2MHz
    30  	PinOutput50MHz PinMode = 3 // Output mode, max speed 50MHz
    31  	PinOutput      PinMode = PinOutput2MHz
    32  
    33  	PinInputModeAnalog     PinMode = 0  // Input analog mode
    34  	PinInputModeFloating   PinMode = 4  // Input floating mode
    35  	PinInputModePullUpDown PinMode = 8  // Input pull up/down mode
    36  	PinInputModeReserved   PinMode = 12 // Input mode (reserved)
    37  
    38  	PinOutputModeGPPushPull   PinMode = 0  // Output mode general purpose push/pull
    39  	PinOutputModeGPOpenDrain  PinMode = 4  // Output mode general purpose open drain
    40  	PinOutputModeAltPushPull  PinMode = 8  // Output mode alt. purpose push/pull
    41  	PinOutputModeAltOpenDrain PinMode = 12 // Output mode alt. purpose open drain
    42  
    43  	// Pull-up vs Pull down is not part of the CNF0 / CNF1 bits, but is
    44  	// controlled by PxODR.  Encoded using the 'spare' bit 5.
    45  	PinInputPulldown PinMode = PinInputModePullUpDown
    46  	PinInputPullup   PinMode = PinInputModePullUpDown | 0x10
    47  )
    48  
    49  // Pin constants for all stm32f103 package sizes
    50  const (
    51  	PA0  = portA + 0
    52  	PA1  = portA + 1
    53  	PA2  = portA + 2
    54  	PA3  = portA + 3
    55  	PA4  = portA + 4
    56  	PA5  = portA + 5
    57  	PA6  = portA + 6
    58  	PA7  = portA + 7
    59  	PA8  = portA + 8
    60  	PA9  = portA + 9
    61  	PA10 = portA + 10
    62  	PA11 = portA + 11
    63  	PA12 = portA + 12
    64  	PA13 = portA + 13
    65  	PA14 = portA + 14
    66  	PA15 = portA + 15
    67  
    68  	PB0  = portB + 0
    69  	PB1  = portB + 1
    70  	PB2  = portB + 2
    71  	PB3  = portB + 3
    72  	PB4  = portB + 4
    73  	PB5  = portB + 5
    74  	PB6  = portB + 6
    75  	PB7  = portB + 7
    76  	PB8  = portB + 8
    77  	PB9  = portB + 9
    78  	PB10 = portB + 10
    79  	PB11 = portB + 11
    80  	PB12 = portB + 12
    81  	PB13 = portB + 13
    82  	PB14 = portB + 14
    83  	PB15 = portB + 15
    84  
    85  	PC0  = portC + 0
    86  	PC1  = portC + 1
    87  	PC2  = portC + 2
    88  	PC3  = portC + 3
    89  	PC4  = portC + 4
    90  	PC5  = portC + 5
    91  	PC6  = portC + 6
    92  	PC7  = portC + 7
    93  	PC8  = portC + 8
    94  	PC9  = portC + 9
    95  	PC10 = portC + 10
    96  	PC11 = portC + 11
    97  	PC12 = portC + 12
    98  	PC13 = portC + 13
    99  	PC14 = portC + 14
   100  	PC15 = portC + 15
   101  
   102  	PD0  = portD + 0
   103  	PD1  = portD + 1
   104  	PD2  = portD + 2
   105  	PD3  = portD + 3
   106  	PD4  = portD + 4
   107  	PD5  = portD + 5
   108  	PD6  = portD + 6
   109  	PD7  = portD + 7
   110  	PD8  = portD + 8
   111  	PD9  = portD + 9
   112  	PD10 = portD + 10
   113  	PD11 = portD + 11
   114  	PD12 = portD + 12
   115  	PD13 = portD + 13
   116  	PD14 = portD + 14
   117  	PD15 = portD + 15
   118  
   119  	PE0  = portE + 0
   120  	PE1  = portE + 1
   121  	PE2  = portE + 2
   122  	PE3  = portE + 3
   123  	PE4  = portE + 4
   124  	PE5  = portE + 5
   125  	PE6  = portE + 6
   126  	PE7  = portE + 7
   127  	PE8  = portE + 8
   128  	PE9  = portE + 9
   129  	PE10 = portE + 10
   130  	PE11 = portE + 11
   131  	PE12 = portE + 12
   132  	PE13 = portE + 13
   133  	PE14 = portE + 14
   134  	PE15 = portE + 15
   135  
   136  	PF0  = portF + 0
   137  	PF1  = portF + 1
   138  	PF2  = portF + 2
   139  	PF3  = portF + 3
   140  	PF4  = portF + 4
   141  	PF5  = portF + 5
   142  	PF6  = portF + 6
   143  	PF7  = portF + 7
   144  	PF8  = portF + 8
   145  	PF9  = portF + 9
   146  	PF10 = portF + 10
   147  	PF11 = portF + 11
   148  	PF12 = portF + 12
   149  	PF13 = portF + 13
   150  	PF14 = portF + 14
   151  	PF15 = portF + 15
   152  )
   153  
   154  // Configure this pin with the given I/O settings.
   155  // stm32f1xx uses different technique for setting the GPIO pins than the stm32f407
   156  func (p Pin) Configure(config PinConfig) {
   157  	// Configure the GPIO pin.
   158  	p.enableClock()
   159  	port := p.getPort()
   160  	pin := uint8(p) % 16
   161  	pos := (pin % 8) * 4
   162  	if pin < 8 {
   163  		port.CRL.ReplaceBits(uint32(config.Mode), 0xf, pos)
   164  	} else {
   165  		port.CRH.ReplaceBits(uint32(config.Mode), 0xf, pos)
   166  	}
   167  
   168  	// If configured for input pull-up or pull-down, set ODR
   169  	// for desired pull-up or pull-down.
   170  	if (config.Mode & 0xf) == PinInputModePullUpDown {
   171  		var pullup uint32
   172  		if config.Mode == PinInputPullup {
   173  			pullup = 1
   174  		}
   175  		port.ODR.ReplaceBits(pullup, 0x1, pin)
   176  	}
   177  }
   178  
   179  func (p Pin) getPort() *stm32.GPIO_Type {
   180  	switch p / 16 {
   181  	case 0:
   182  		return stm32.GPIOA
   183  	case 1:
   184  		return stm32.GPIOB
   185  	case 2:
   186  		return stm32.GPIOC
   187  	case 3:
   188  		return stm32.GPIOD
   189  	case 4:
   190  		return stm32.GPIOE
   191  	case 5:
   192  		return stm32.GPIOF
   193  	case 6:
   194  		return stm32.GPIOG
   195  	default:
   196  		panic("machine: unknown port")
   197  	}
   198  }
   199  
   200  // enableClock enables the clock for this desired GPIO port.
   201  func (p Pin) enableClock() {
   202  	switch p / 16 {
   203  	case 0:
   204  		stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_IOPAEN)
   205  	case 1:
   206  		stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_IOPBEN)
   207  	case 2:
   208  		stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_IOPCEN)
   209  	case 3:
   210  		stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_IOPDEN)
   211  	case 4:
   212  		stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_IOPEEN)
   213  	case 5:
   214  		stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_IOPFEN)
   215  	case 6:
   216  		stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_IOPGEN)
   217  	default:
   218  		panic("machine: unknown port")
   219  	}
   220  }
   221  
   222  // Enable peripheral clock. Expand to include all the desired peripherals
   223  func enableAltFuncClock(bus unsafe.Pointer) {
   224  	if bus == unsafe.Pointer(stm32.USART1) {
   225  		stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_USART1EN)
   226  	} else if bus == unsafe.Pointer(stm32.USART2) {
   227  		stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_USART2EN)
   228  	} else if bus == unsafe.Pointer(stm32.I2C1) {
   229  		stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_I2C1EN)
   230  	} else if bus == unsafe.Pointer(stm32.SPI1) {
   231  		stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_SPI1EN)
   232  	}
   233  }
   234  
   235  func (p Pin) registerInterrupt() interrupt.Interrupt {
   236  	pin := uint8(p) % 16
   237  
   238  	switch pin {
   239  	case 0:
   240  		return interrupt.New(stm32.IRQ_EXTI0, func(interrupt.Interrupt) { handlePinInterrupt(0) })
   241  	case 1:
   242  		return interrupt.New(stm32.IRQ_EXTI1, func(interrupt.Interrupt) { handlePinInterrupt(1) })
   243  	case 2:
   244  		return interrupt.New(stm32.IRQ_EXTI2, func(interrupt.Interrupt) { handlePinInterrupt(2) })
   245  	case 3:
   246  		return interrupt.New(stm32.IRQ_EXTI3, func(interrupt.Interrupt) { handlePinInterrupt(3) })
   247  	case 4:
   248  		return interrupt.New(stm32.IRQ_EXTI4, func(interrupt.Interrupt) { handlePinInterrupt(4) })
   249  	case 5:
   250  		return interrupt.New(stm32.IRQ_EXTI9_5, func(interrupt.Interrupt) { handlePinInterrupt(5) })
   251  	case 6:
   252  		return interrupt.New(stm32.IRQ_EXTI9_5, func(interrupt.Interrupt) { handlePinInterrupt(6) })
   253  	case 7:
   254  		return interrupt.New(stm32.IRQ_EXTI9_5, func(interrupt.Interrupt) { handlePinInterrupt(7) })
   255  	case 8:
   256  		return interrupt.New(stm32.IRQ_EXTI9_5, func(interrupt.Interrupt) { handlePinInterrupt(8) })
   257  	case 9:
   258  		return interrupt.New(stm32.IRQ_EXTI9_5, func(interrupt.Interrupt) { handlePinInterrupt(9) })
   259  	case 10:
   260  		return interrupt.New(stm32.IRQ_EXTI15_10, func(interrupt.Interrupt) { handlePinInterrupt(10) })
   261  	case 11:
   262  		return interrupt.New(stm32.IRQ_EXTI15_10, func(interrupt.Interrupt) { handlePinInterrupt(11) })
   263  	case 12:
   264  		return interrupt.New(stm32.IRQ_EXTI15_10, func(interrupt.Interrupt) { handlePinInterrupt(12) })
   265  	case 13:
   266  		return interrupt.New(stm32.IRQ_EXTI15_10, func(interrupt.Interrupt) { handlePinInterrupt(13) })
   267  	case 14:
   268  		return interrupt.New(stm32.IRQ_EXTI15_10, func(interrupt.Interrupt) { handlePinInterrupt(14) })
   269  	case 15:
   270  		return interrupt.New(stm32.IRQ_EXTI15_10, func(interrupt.Interrupt) { handlePinInterrupt(15) })
   271  	}
   272  
   273  	return interrupt.Interrupt{}
   274  }
   275  
   276  //---------- UART related code
   277  
   278  // Configure the TX and RX pins
   279  func (uart *UART) configurePins(config UARTConfig) {
   280  
   281  	// pins
   282  	switch config.TX {
   283  	case UART_ALT_TX_PIN:
   284  		// use alternate TX/RX pins via AFIO mapping
   285  		stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_AFIOEN)
   286  		if uart.Bus == stm32.USART1 {
   287  			stm32.AFIO.MAPR.SetBits(stm32.AFIO_MAPR_USART1_REMAP)
   288  		} else if uart.Bus == stm32.USART2 {
   289  			stm32.AFIO.MAPR.SetBits(stm32.AFIO_MAPR_USART2_REMAP)
   290  		}
   291  	default:
   292  		// use standard TX/RX pins PA9 and PA10
   293  	}
   294  	config.TX.Configure(PinConfig{Mode: PinOutput50MHz + PinOutputModeAltPushPull})
   295  	config.RX.Configure(PinConfig{Mode: PinInputModeFloating})
   296  }
   297  
   298  // Determine the divisor for USARTs to get the given baudrate
   299  func (uart *UART) getBaudRateDivisor(br uint32) uint32 {
   300  
   301  	// Note: PCLK2 (from APB2) used for USART1 and PCLK1 for USART2, 3, 4, 5
   302  	var divider uint32
   303  	if uart.Bus == stm32.USART1 {
   304  		// first divide by PCLK2 prescaler (div 1) and then desired baudrate
   305  		divider = CPUFrequency() / br
   306  	} else {
   307  		// first divide by PCLK1 prescaler (div 2) and then desired baudrate
   308  		divider = CPUFrequency() / 2 / br
   309  	}
   310  	return divider
   311  }
   312  
   313  // Register names vary by ST processor, these are for STM F103xx
   314  func (uart *UART) setRegisters() {
   315  	uart.rxReg = &uart.Bus.DR
   316  	uart.txReg = &uart.Bus.DR
   317  	uart.statusReg = &uart.Bus.SR
   318  	uart.txEmptyFlag = stm32.USART_SR_TXE
   319  }
   320  
   321  //---------- SPI related types and code
   322  
   323  type SPI struct {
   324  	Bus *stm32.SPI_Type
   325  }
   326  
   327  // There are 3 SPI interfaces on the STM32F103xx.
   328  // Since the first interface is named SPI1, both SPI0 and SPI1 refer to SPI1.
   329  // TODO: implement SPI2 and SPI3.
   330  var (
   331  	SPI1 = SPI{Bus: stm32.SPI1}
   332  	SPI0 = SPI1
   333  )
   334  
   335  func (spi SPI) config8Bits() {
   336  	// no-op on this series
   337  }
   338  
   339  // Set baud rate for SPI
   340  func (spi SPI) getBaudRate(config SPIConfig) uint32 {
   341  	var conf uint32
   342  
   343  	// set frequency dependent on PCLK2 prescaler (div 1)
   344  	switch {
   345  	case config.Frequency < 125000:
   346  		// Note: impossible to achieve lower frequency with current PCLK2!
   347  		conf |= stm32.SPI_CR1_BR_Div256
   348  	case config.Frequency < 250000:
   349  		conf |= stm32.SPI_CR1_BR_Div256
   350  	case config.Frequency < 500000:
   351  		conf |= stm32.SPI_CR1_BR_Div128
   352  	case config.Frequency < 1000000:
   353  		conf |= stm32.SPI_CR1_BR_Div64
   354  	case config.Frequency < 2000000:
   355  		conf |= stm32.SPI_CR1_BR_Div32
   356  	case config.Frequency < 4000000:
   357  		conf |= stm32.SPI_CR1_BR_Div16
   358  	default:
   359  		// When its bigger than Div16, just round to the maximum frequency.
   360  		conf |= stm32.SPI_CR1_BR_Div8
   361  	}
   362  	return conf << stm32.SPI_CR1_BR_Pos
   363  }
   364  
   365  // Configure SPI pins for input output and clock
   366  func (spi SPI) configurePins(config SPIConfig) {
   367  	config.SCK.Configure(PinConfig{Mode: PinOutput50MHz + PinOutputModeAltPushPull})
   368  	config.SDO.Configure(PinConfig{Mode: PinOutput50MHz + PinOutputModeAltPushPull})
   369  	config.SDI.Configure(PinConfig{Mode: PinInputModeFloating})
   370  }
   371  
   372  //---------- I2C related types and code
   373  
   374  // There are 2 I2C interfaces on the STM32F103xx.
   375  // Since the first interface is named I2C1, both I2C0 and I2C1 refer to I2C1.
   376  // TODO: implement I2C2.
   377  
   378  type I2C struct {
   379  	Bus *stm32.I2C_Type
   380  }
   381  
   382  var (
   383  	I2C1 = &I2C{Bus: stm32.I2C1}
   384  	I2C0 = I2C1
   385  )
   386  
   387  func (i2c *I2C) configurePins(config I2CConfig) {
   388  	if config.SDA == PB9 {
   389  		// use alternate I2C1 pins PB8/PB9 via AFIO mapping
   390  		stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_AFIOEN)
   391  		stm32.AFIO.MAPR.SetBits(stm32.AFIO_MAPR_I2C1_REMAP)
   392  	}
   393  
   394  	config.SDA.Configure(PinConfig{Mode: PinOutput50MHz + PinOutputModeAltOpenDrain})
   395  	config.SCL.Configure(PinConfig{Mode: PinOutput50MHz + PinOutputModeAltOpenDrain})
   396  }
   397  
   398  func (i2c *I2C) getFreqRange(config I2CConfig) uint32 {
   399  	// pclk1 clock speed is main frequency divided by PCLK1 prescaler (div 2)
   400  	pclk1 := CPUFrequency() / 2
   401  
   402  	// set freqency range to PCLK1 clock speed in MHz
   403  	// aka setting the value 36 means to use 36 MHz clock
   404  	return pclk1 / 1000000
   405  }
   406  
   407  func (i2c *I2C) getRiseTime(config I2CConfig) uint32 {
   408  	// These bits must be programmed with the maximum SCL rise time given in the
   409  	// I2C bus specification, incremented by 1.
   410  	// For instance: in Sm mode, the maximum allowed SCL rise time is 1000 ns.
   411  	// If, in the I2C_CR2 register, the value of FREQ[5:0] bits is equal to 0x08
   412  	// and PCLK1 = 125 ns, therefore the TRISE[5:0] bits must be programmed with
   413  	// 09h (1000 ns / 125 ns = 8 + 1)
   414  	freqRange := i2c.getFreqRange(config)
   415  	if config.Frequency > 100000 {
   416  		// fast mode (Fm) adjustment
   417  		freqRange *= 300
   418  		freqRange /= 1000
   419  	}
   420  	return (freqRange + 1) << stm32.I2C_TRISE_TRISE_Pos
   421  }
   422  
   423  func (i2c *I2C) getSpeed(config I2CConfig) uint32 {
   424  	ccr := func(pclk uint32, freq uint32, coeff uint32) uint32 {
   425  		return (((pclk - 1) / (freq * coeff)) + 1) & stm32.I2C_CCR_CCR_Msk
   426  	}
   427  	sm := func(pclk uint32, freq uint32) uint32 { // standard mode (Sm)
   428  		if s := ccr(pclk, freq, 2); s < 4 {
   429  			return 4
   430  		} else {
   431  			return s
   432  		}
   433  	}
   434  	fm := func(pclk uint32, freq uint32, duty uint8) uint32 { // fast mode (Fm)
   435  		if duty == DutyCycle2 {
   436  			return ccr(pclk, freq, 3)
   437  		} else {
   438  			return ccr(pclk, freq, 25) | stm32.I2C_CCR_DUTY
   439  		}
   440  	}
   441  	clock := CPUFrequency() / 2
   442  	if config.Frequency <= 100000 {
   443  		return sm(clock, config.Frequency)
   444  	} else {
   445  		s := fm(clock, config.Frequency, config.DutyCycle)
   446  		if (s & stm32.I2C_CCR_CCR_Msk) == 0 {
   447  			return 1
   448  		} else {
   449  			return s | stm32.I2C_CCR_F_S
   450  		}
   451  	}
   452  }
   453  
   454  //---------- Timer related code
   455  
   456  // For Pin Mappings see RM0008, pg 179
   457  // https://www.st.com/resource/en/reference_manual/cd00171190-stm32f101xx-stm32f102xx-stm32f103xx-stm32f105xx-and-stm32f107xx-advanced-arm-based-32-bit-mcus-stmicroelectronics.pdf
   458  //
   459  // Note: for STM32F1 series the pin mapping is done 'per timer' not per channel,
   460  // not all channels on a timer have the same degrees of flexibility, and some
   461  // combinations are only available on some packages - so care is needed at app
   462  // level to ensure valid combinations of pins are used.
   463  //
   464  
   465  var (
   466  	TIM1 = TIM{
   467  		EnableRegister: &stm32.RCC.APB2ENR,
   468  		EnableFlag:     stm32.RCC_APB2ENR_TIM1EN,
   469  		Device:         stm32.TIM1,
   470  		Channels: [4]TimerChannel{
   471  			TimerChannel{Pins: []PinFunction{{PE9, 0b11}, {PA8, 0b00}}},
   472  			TimerChannel{Pins: []PinFunction{{PE11, 0b11}, {PA9, 0b00}}},
   473  			TimerChannel{Pins: []PinFunction{{PE13, 0b11}, {PA10, 0b00}}},
   474  			TimerChannel{Pins: []PinFunction{{PE14, 0b11}, {PA11, 0b00}}},
   475  		},
   476  		busFreq: APB2_TIM_FREQ,
   477  	}
   478  
   479  	TIM2 = TIM{
   480  		EnableRegister: &stm32.RCC.APB1ENR,
   481  		EnableFlag:     stm32.RCC_APB1ENR_TIM2EN,
   482  		Device:         stm32.TIM2,
   483  		Channels: [4]TimerChannel{
   484  			TimerChannel{Pins: []PinFunction{{PA0, 0b00}, {PA15, 0b01}}},
   485  			TimerChannel{Pins: []PinFunction{{PA1, 0b00}, {PB3, 0b01}}},
   486  			TimerChannel{Pins: []PinFunction{{PA2, 0b00}, {PB10, 0b10}}},
   487  			TimerChannel{Pins: []PinFunction{{PA3, 0b00}, {PB11, 0b10}}},
   488  		},
   489  		busFreq: APB1_TIM_FREQ,
   490  	}
   491  
   492  	TIM3 = TIM{
   493  		EnableRegister: &stm32.RCC.APB1ENR,
   494  		EnableFlag:     stm32.RCC_APB1ENR_TIM3EN,
   495  		Device:         stm32.TIM3,
   496  		Channels: [4]TimerChannel{
   497  			TimerChannel{Pins: []PinFunction{{PA6, 0b00}, {PC6, 0b11}, {PB4, 0b10}}},
   498  			TimerChannel{Pins: []PinFunction{{PA7, 0b00}, {PC7, 0b11}, {PB5, 0b10}}},
   499  			TimerChannel{Pins: []PinFunction{{PB0, 0b00}, {PC8, 0b11}}},
   500  			TimerChannel{Pins: []PinFunction{{PB1, 0b00}, {PC9, 0b11}}},
   501  		},
   502  		busFreq: APB1_TIM_FREQ,
   503  	}
   504  
   505  	TIM4 = TIM{
   506  		EnableRegister: &stm32.RCC.APB1ENR,
   507  		EnableFlag:     stm32.RCC_APB1ENR_TIM4EN,
   508  		Device:         stm32.TIM4,
   509  		Channels: [4]TimerChannel{
   510  			TimerChannel{Pins: []PinFunction{{PD12, 0b1}, {PB6, 0}}},
   511  			TimerChannel{Pins: []PinFunction{{PD13, 0b1}, {PB7, 0}}},
   512  			TimerChannel{Pins: []PinFunction{{PD14, 0b1}, {PB8, 0}}},
   513  			TimerChannel{Pins: []PinFunction{{PD15, 0b1}, {PB9, 0}}},
   514  		},
   515  		busFreq: APB1_TIM_FREQ,
   516  	}
   517  
   518  	TIM5 = TIM{
   519  		EnableRegister: &stm32.RCC.APB1ENR,
   520  		EnableFlag:     stm32.RCC_APB1ENR_TIM5EN,
   521  		Device:         stm32.TIM5,
   522  		Channels: [4]TimerChannel{
   523  			TimerChannel{Pins: []PinFunction{}},
   524  			TimerChannel{Pins: []PinFunction{}},
   525  			TimerChannel{Pins: []PinFunction{}},
   526  			TimerChannel{Pins: []PinFunction{{PA3, 0b0}}},
   527  		},
   528  		busFreq: APB1_TIM_FREQ,
   529  	}
   530  
   531  	TIM6 = TIM{
   532  		EnableRegister: &stm32.RCC.APB1ENR,
   533  		EnableFlag:     stm32.RCC_APB1ENR_TIM6EN,
   534  		Device:         stm32.TIM6,
   535  		Channels: [4]TimerChannel{
   536  			TimerChannel{Pins: []PinFunction{}},
   537  			TimerChannel{Pins: []PinFunction{}},
   538  			TimerChannel{Pins: []PinFunction{}},
   539  			TimerChannel{Pins: []PinFunction{}},
   540  		},
   541  		busFreq: APB1_TIM_FREQ,
   542  	}
   543  
   544  	TIM7 = TIM{
   545  		EnableRegister: &stm32.RCC.APB1ENR,
   546  		EnableFlag:     stm32.RCC_APB1ENR_TIM7EN,
   547  		Device:         stm32.TIM7,
   548  		Channels: [4]TimerChannel{
   549  			TimerChannel{Pins: []PinFunction{}},
   550  			TimerChannel{Pins: []PinFunction{}},
   551  			TimerChannel{Pins: []PinFunction{}},
   552  			TimerChannel{Pins: []PinFunction{}},
   553  		},
   554  		busFreq: APB1_TIM_FREQ,
   555  	}
   556  
   557  	TIM8 = TIM{
   558  		EnableRegister: &stm32.RCC.APB2ENR,
   559  		EnableFlag:     stm32.RCC_APB2ENR_TIM8EN,
   560  		Device:         stm32.TIM8,
   561  		Channels: [4]TimerChannel{
   562  			TimerChannel{Pins: []PinFunction{}},
   563  			TimerChannel{Pins: []PinFunction{}},
   564  			TimerChannel{Pins: []PinFunction{}},
   565  			TimerChannel{Pins: []PinFunction{}},
   566  		},
   567  		busFreq: APB2_TIM_FREQ,
   568  	}
   569  
   570  	TIM9 = TIM{
   571  		EnableRegister: &stm32.RCC.APB2ENR,
   572  		EnableFlag:     stm32.RCC_APB2ENR_TIM9EN,
   573  		Device:         stm32.TIM9,
   574  		Channels: [4]TimerChannel{
   575  			TimerChannel{Pins: []PinFunction{{PA2, 0b0}, {PE5, 0b1}}},
   576  			TimerChannel{Pins: []PinFunction{{PA3, 0b0}, {PE6, 0b1}}},
   577  			TimerChannel{Pins: []PinFunction{}},
   578  			TimerChannel{Pins: []PinFunction{}},
   579  		},
   580  		busFreq: APB2_TIM_FREQ,
   581  	}
   582  
   583  	TIM10 = TIM{
   584  		EnableRegister: &stm32.RCC.APB2ENR,
   585  		EnableFlag:     stm32.RCC_APB2ENR_TIM10EN,
   586  		Device:         stm32.TIM10,
   587  		Channels: [4]TimerChannel{
   588  			TimerChannel{Pins: []PinFunction{{PB8, 0b0}, {PF6, 0b1}}},
   589  			TimerChannel{Pins: []PinFunction{}},
   590  			TimerChannel{Pins: []PinFunction{}},
   591  			TimerChannel{Pins: []PinFunction{}},
   592  		},
   593  		busFreq: APB2_TIM_FREQ,
   594  	}
   595  
   596  	TIM11 = TIM{
   597  		EnableRegister: &stm32.RCC.APB2ENR,
   598  		EnableFlag:     stm32.RCC_APB2ENR_TIM11EN,
   599  		Device:         stm32.TIM11,
   600  		Channels: [4]TimerChannel{
   601  			TimerChannel{Pins: []PinFunction{{PB9, 0b0}, {PF7, 0b1}}},
   602  			TimerChannel{Pins: []PinFunction{}},
   603  			TimerChannel{Pins: []PinFunction{}},
   604  			TimerChannel{Pins: []PinFunction{}},
   605  		},
   606  		busFreq: APB2_TIM_FREQ,
   607  	}
   608  
   609  	TIM12 = TIM{
   610  		EnableRegister: &stm32.RCC.APB1ENR,
   611  		EnableFlag:     stm32.RCC_APB1ENR_TIM12EN,
   612  		Device:         stm32.TIM12,
   613  		Channels: [4]TimerChannel{
   614  			TimerChannel{Pins: []PinFunction{{}}},
   615  			TimerChannel{Pins: []PinFunction{}},
   616  			TimerChannel{Pins: []PinFunction{}},
   617  			TimerChannel{Pins: []PinFunction{}},
   618  		},
   619  		busFreq: APB1_TIM_FREQ,
   620  	}
   621  
   622  	TIM13 = TIM{
   623  		EnableRegister: &stm32.RCC.APB1ENR,
   624  		EnableFlag:     stm32.RCC_APB1ENR_TIM13EN,
   625  		Device:         stm32.TIM13,
   626  		Channels: [4]TimerChannel{
   627  			TimerChannel{Pins: []PinFunction{{PA6, 0b0}, {PF8, 0b1}}},
   628  			TimerChannel{Pins: []PinFunction{}},
   629  			TimerChannel{Pins: []PinFunction{}},
   630  			TimerChannel{Pins: []PinFunction{}},
   631  		},
   632  		busFreq: APB1_TIM_FREQ,
   633  	}
   634  
   635  	TIM14 = TIM{
   636  		EnableRegister: &stm32.RCC.APB1ENR,
   637  		EnableFlag:     stm32.RCC_APB1ENR_TIM14EN,
   638  		Device:         stm32.TIM14,
   639  		Channels: [4]TimerChannel{
   640  			TimerChannel{Pins: []PinFunction{{PA7, 0b0}, {PF9, 0b1}}},
   641  			TimerChannel{Pins: []PinFunction{}},
   642  			TimerChannel{Pins: []PinFunction{}},
   643  			TimerChannel{Pins: []PinFunction{}},
   644  		},
   645  		busFreq: APB1_TIM_FREQ,
   646  	}
   647  )
   648  
   649  func (t *TIM) registerUPInterrupt() interrupt.Interrupt {
   650  	switch t {
   651  	case &TIM1:
   652  		return interrupt.New(stm32.IRQ_TIM1_UP, TIM1.handleUPInterrupt)
   653  	case &TIM2:
   654  		return interrupt.New(stm32.IRQ_TIM2, TIM2.handleUPInterrupt)
   655  	case &TIM3:
   656  		return interrupt.New(stm32.IRQ_TIM3, TIM3.handleUPInterrupt)
   657  	case &TIM4:
   658  		return interrupt.New(stm32.IRQ_TIM4, TIM4.handleUPInterrupt)
   659  	case &TIM5:
   660  		return interrupt.New(stm32.IRQ_TIM5, TIM5.handleUPInterrupt)
   661  	case &TIM6:
   662  		return interrupt.New(stm32.IRQ_TIM6, TIM6.handleUPInterrupt)
   663  	case &TIM7:
   664  		return interrupt.New(stm32.IRQ_TIM7, TIM7.handleUPInterrupt)
   665  	case &TIM8:
   666  		return interrupt.New(stm32.IRQ_TIM8_UP, TIM8.handleUPInterrupt)
   667  	}
   668  
   669  	return interrupt.Interrupt{}
   670  }
   671  
   672  func (t *TIM) registerOCInterrupt() interrupt.Interrupt {
   673  	switch t {
   674  	case &TIM1:
   675  		return interrupt.New(stm32.IRQ_TIM1_CC, TIM1.handleOCInterrupt)
   676  	case &TIM2:
   677  		return interrupt.New(stm32.IRQ_TIM2, TIM2.handleOCInterrupt)
   678  	case &TIM3:
   679  		return interrupt.New(stm32.IRQ_TIM3, TIM3.handleOCInterrupt)
   680  	case &TIM4:
   681  		return interrupt.New(stm32.IRQ_TIM4, TIM4.handleOCInterrupt)
   682  	case &TIM5:
   683  		return interrupt.New(stm32.IRQ_TIM5, TIM5.handleOCInterrupt)
   684  	case &TIM6:
   685  		return interrupt.New(stm32.IRQ_TIM6, TIM6.handleOCInterrupt)
   686  	case &TIM7:
   687  		return interrupt.New(stm32.IRQ_TIM7, TIM7.handleOCInterrupt)
   688  	case &TIM8:
   689  		return interrupt.New(stm32.IRQ_TIM8_CC, TIM8.handleOCInterrupt)
   690  	}
   691  
   692  	return interrupt.Interrupt{}
   693  }
   694  
   695  func (t *TIM) configurePin(channel uint8, pf PinFunction) {
   696  	remap := uint32(pf.AltFunc)
   697  
   698  	switch t {
   699  	case &TIM1:
   700  		stm32.AFIO.MAPR.ReplaceBits(remap<<stm32.AFIO_MAPR_TIM1_REMAP_Pos, stm32.AFIO_MAPR_TIM1_REMAP_Msk, 0)
   701  	case &TIM2:
   702  		stm32.AFIO.MAPR.ReplaceBits(remap<<stm32.AFIO_MAPR_TIM2_REMAP_Pos, stm32.AFIO_MAPR_TIM2_REMAP_Msk, 0)
   703  	case &TIM3:
   704  		stm32.AFIO.MAPR.ReplaceBits(remap<<stm32.AFIO_MAPR_TIM3_REMAP_Pos, stm32.AFIO_MAPR_TIM3_REMAP_Msk, 0)
   705  	case &TIM4:
   706  		stm32.AFIO.MAPR.ReplaceBits(remap<<stm32.AFIO_MAPR_TIM4_REMAP_Pos, stm32.AFIO_MAPR_TIM4_REMAP_Msk, 0)
   707  	case &TIM5:
   708  		stm32.AFIO.MAPR.ReplaceBits(remap<<stm32.AFIO_MAPR_TIM5CH4_IREMAP_Pos, stm32.AFIO_MAPR_TIM5CH4_IREMAP_Msk, 0)
   709  	case &TIM9:
   710  		stm32.AFIO.MAPR.ReplaceBits(remap<<stm32.AFIO_MAPR2_TIM9_REMAP_Pos, stm32.AFIO_MAPR2_TIM9_REMAP_Msk, 0)
   711  	case &TIM10:
   712  		stm32.AFIO.MAPR.ReplaceBits(remap<<stm32.AFIO_MAPR2_TIM10_REMAP_Pos, stm32.AFIO_MAPR2_TIM10_REMAP_Msk, 0)
   713  	case &TIM11:
   714  		stm32.AFIO.MAPR.ReplaceBits(remap<<stm32.AFIO_MAPR2_TIM11_REMAP_Pos, stm32.AFIO_MAPR2_TIM11_REMAP_Msk, 0)
   715  	case &TIM13:
   716  		stm32.AFIO.MAPR.ReplaceBits(remap<<stm32.AFIO_MAPR2_TIM13_REMAP_Pos, stm32.AFIO_MAPR2_TIM13_REMAP_Msk, 0)
   717  	case &TIM14:
   718  		stm32.AFIO.MAPR.ReplaceBits(remap<<stm32.AFIO_MAPR2_TIM14_REMAP_Pos, stm32.AFIO_MAPR2_TIM14_REMAP_Msk, 0)
   719  	}
   720  
   721  	pf.Pin.Configure(PinConfig{Mode: PinOutput + PinOutputModeAltPushPull})
   722  }
   723  
   724  func (t *TIM) enableMainOutput() {
   725  	t.Device.BDTR.SetBits(stm32.TIM_BDTR_MOE)
   726  }
   727  
   728  type arrtype = uint32
   729  type arrRegType = volatile.Register32
   730  
   731  const (
   732  	ARR_MAX = 0x10000
   733  	PSC_MAX = 0x10000
   734  )