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 )