github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/src/machine/machine_stm32wlx.go (about) 1 //go:build stm32wlx 2 3 package machine 4 5 // Peripheral abstraction layer for the stm32wle5 6 7 import ( 8 "device/stm32" 9 "encoding/binary" 10 "errors" 11 "math/bits" 12 "runtime/interrupt" 13 "runtime/volatile" 14 "unsafe" 15 ) 16 17 var deviceIDAddr = []uintptr{0x1FFF7590, 0x1FFF7594, 0x1FFF7598} 18 19 const ( 20 AF0_SYSTEM = 0 21 AF1_TIM1_2_LPTIM1 = 1 22 AF2_TIM1_2 = 2 23 AF3_SPIS2_TIM1_LPTIM3 = 3 24 AF4_I2C1_2_3 = 4 25 AF5_SPI1_SPI2S2 = 5 26 AF6_RF = 6 27 AF7_USART1_2 = 7 28 AF8_LPUART1 = 8 29 AF12_COMP1_2_TIM1 = 12 30 AF13_DEBUG = 13 31 AF14_TIM2_16_17_LPTIM2 = 14 32 AF15_EVENTOUT = 15 33 ) 34 35 const ( 36 SYSCLK = 48e6 37 APB1_TIM_FREQ = SYSCLK 38 APB2_TIM_FREQ = SYSCLK 39 ) 40 41 func CPUFrequency() uint32 { 42 return SYSCLK 43 } 44 45 const ( 46 PA0 = portA + 0 47 PA1 = portA + 1 48 PA2 = portA + 2 49 PA3 = portA + 3 50 PA4 = portA + 4 51 PA5 = portA + 5 52 PA6 = portA + 6 53 PA7 = portA + 7 54 PA8 = portA + 8 55 PA9 = portA + 9 56 PA10 = portA + 10 57 PA11 = portA + 11 58 PA12 = portA + 12 59 PA13 = portA + 13 60 PA14 = portA + 14 61 PA15 = portA + 15 62 63 PB0 = portB + 0 64 PB1 = portB + 1 65 PB2 = portB + 2 66 PB3 = portB + 3 67 PB4 = portB + 4 68 PB5 = portB + 5 69 PB6 = portB + 6 70 PB7 = portB + 7 71 PB8 = portB + 8 72 PB9 = portB + 9 73 PB10 = portB + 10 74 PB11 = portB + 11 75 PB12 = portB + 12 76 PB13 = portB + 13 77 PB14 = portB + 14 78 PB15 = portB + 15 79 80 PC0 = portC + 0 81 PC1 = portC + 1 82 PC2 = portC + 2 83 PC3 = portC + 3 84 PC4 = portC + 4 85 PC5 = portC + 5 86 PC6 = portC + 6 87 PC7 = portC + 7 88 PC8 = portC + 8 89 PC9 = portC + 9 90 PC10 = portC + 10 91 PC11 = portC + 11 92 PC12 = portC + 12 93 PC13 = portC + 13 94 PC14 = portC + 14 95 PC15 = portC + 15 96 97 PH3 = portH + 3 98 ) 99 100 func (p Pin) getPort() *stm32.GPIO_Type { 101 switch p / 16 { 102 case 0: 103 return stm32.GPIOA 104 case 1: 105 return stm32.GPIOB 106 case 2: 107 return stm32.GPIOC 108 case 7: 109 return stm32.GPIOH 110 default: 111 panic("machine: unknown port") 112 } 113 } 114 115 // enableClock enables the clock for this desired GPIO port. 116 func (p Pin) enableClock() { 117 switch p / 16 { 118 case 0: 119 stm32.RCC.AHB2ENR.SetBits(stm32.RCC_AHB2ENR_GPIOAEN) 120 case 1: 121 stm32.RCC.AHB2ENR.SetBits(stm32.RCC_AHB2ENR_GPIOBEN) 122 case 2: 123 stm32.RCC.AHB2ENR.SetBits(stm32.RCC_AHB2ENR_GPIOCEN) 124 case 7: 125 stm32.RCC.AHB2ENR.SetBits(stm32.RCC_AHB2ENR_GPIOHEN) 126 default: 127 panic("machine: unknown port") 128 } 129 } 130 131 // Enable peripheral clock 132 func enableAltFuncClock(bus unsafe.Pointer) { 133 switch bus { 134 // APB1ENR1 135 case unsafe.Pointer(stm32.LPTIM1): // LPTIM1 clock enable 136 stm32.RCC.APB1ENR1.SetBits(stm32.RCC_APB1ENR1_LPTIM1EN) 137 case unsafe.Pointer(stm32.DAC): // DAC clock enable 138 stm32.RCC.APB1ENR1.SetBits(stm32.RCC_APB1ENR1_DAC1EN) 139 case unsafe.Pointer(stm32.I2C3): // I2C3 clock enable 140 stm32.RCC.APB1ENR1.SetBits(stm32.RCC_APB1ENR1_I2C3EN) 141 case unsafe.Pointer(stm32.I2C2): // I2C2 clock enable 142 stm32.RCC.APB1ENR1.SetBits(stm32.RCC_APB1ENR1_I2C2EN) 143 case unsafe.Pointer(stm32.I2C1): // I2C1 clock enable 144 stm32.RCC.APB1ENR1.SetBits(stm32.RCC_APB1ENR1_I2C1EN) 145 case unsafe.Pointer(stm32.USART2): // USART2 clock enable 146 stm32.RCC.APB1ENR1.SetBits(stm32.RCC_APB1ENR1_USART2EN) 147 case unsafe.Pointer(stm32.SPI2): // SPI2S2 clock enable 148 stm32.RCC.APB1ENR1.SetBits(stm32.RCC_APB1ENR1_SPI2S2EN) 149 case unsafe.Pointer(stm32.WWDG): // Window watchdog clock enable 150 stm32.RCC.APB1ENR1.SetBits(stm32.RCC_APB1ENR1_WWDGEN) 151 case unsafe.Pointer(stm32.TIM2): // TIM2 clock enable 152 stm32.RCC.APB1ENR1.SetBits(stm32.RCC_APB1ENR1_TIM2EN) 153 // APB1ENR2 154 case unsafe.Pointer(stm32.LPTIM3): // LPTIM3 clock enable 155 stm32.RCC.APB1ENR2.SetBits(stm32.RCC_APB1ENR2_LPTIM3EN) 156 case unsafe.Pointer(stm32.LPTIM2): // LPTIM2 clock enable 157 stm32.RCC.APB1ENR2.SetBits(stm32.RCC_APB1ENR2_LPTIM2EN) 158 case unsafe.Pointer(stm32.LPUART): // LPUART clock enable 159 stm32.RCC.APB1ENR2.SetBits(stm32.RCC_APB1ENR2_LPUART1EN) 160 //APB2ENR 161 case unsafe.Pointer(stm32.TIM17): // TIM17 clock enable 162 stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_TIM17EN) 163 case unsafe.Pointer(stm32.TIM16): // TIM16 clock enable 164 stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_TIM16EN) 165 case unsafe.Pointer(stm32.USART1): // USART1 clock enable 166 stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_USART1EN) 167 case unsafe.Pointer(stm32.SPI1): // SPI1 clock enable 168 stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_SPI1EN) 169 case unsafe.Pointer(stm32.TIM1): // TIM1 clock enable 170 stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_TIM1EN) 171 case unsafe.Pointer(stm32.ADC): // ADC clock enable 172 stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_ADCEN) 173 174 } 175 } 176 177 func handlePinInterrupt(pin uint8) { 178 if stm32.EXTI.PR1.HasBits(1 << pin) { 179 // Writing 1 to the pending register clears the 180 // pending flag for that bit 181 stm32.EXTI.PR1.Set(1 << pin) 182 183 callback := pinCallbacks[pin] 184 if callback != nil { 185 callback(interruptPins[pin]) 186 } 187 } 188 } 189 190 func (p Pin) registerInterrupt() interrupt.Interrupt { 191 pin := uint8(p) % 16 192 193 switch pin { 194 case 0: 195 return interrupt.New(stm32.IRQ_EXTI0, func(interrupt.Interrupt) { handlePinInterrupt(0) }) 196 case 1: 197 return interrupt.New(stm32.IRQ_EXTI1, func(interrupt.Interrupt) { handlePinInterrupt(1) }) 198 case 2: 199 return interrupt.New(stm32.IRQ_EXTI2, func(interrupt.Interrupt) { handlePinInterrupt(2) }) 200 case 3: 201 return interrupt.New(stm32.IRQ_EXTI3, func(interrupt.Interrupt) { handlePinInterrupt(3) }) 202 case 4: 203 return interrupt.New(stm32.IRQ_EXTI4, func(interrupt.Interrupt) { handlePinInterrupt(4) }) 204 case 5: 205 return interrupt.New(stm32.IRQ_EXTI9_5, func(interrupt.Interrupt) { handlePinInterrupt(5) }) 206 case 6: 207 return interrupt.New(stm32.IRQ_EXTI9_5, func(interrupt.Interrupt) { handlePinInterrupt(6) }) 208 case 7: 209 return interrupt.New(stm32.IRQ_EXTI9_5, func(interrupt.Interrupt) { handlePinInterrupt(7) }) 210 case 8: 211 return interrupt.New(stm32.IRQ_EXTI9_5, func(interrupt.Interrupt) { handlePinInterrupt(8) }) 212 case 9: 213 return interrupt.New(stm32.IRQ_EXTI9_5, func(interrupt.Interrupt) { handlePinInterrupt(9) }) 214 case 10: 215 return interrupt.New(stm32.IRQ_EXTI15_10, func(interrupt.Interrupt) { handlePinInterrupt(10) }) 216 case 11: 217 return interrupt.New(stm32.IRQ_EXTI15_10, func(interrupt.Interrupt) { handlePinInterrupt(11) }) 218 case 12: 219 return interrupt.New(stm32.IRQ_EXTI15_10, func(interrupt.Interrupt) { handlePinInterrupt(12) }) 220 case 13: 221 return interrupt.New(stm32.IRQ_EXTI15_10, func(interrupt.Interrupt) { handlePinInterrupt(13) }) 222 case 14: 223 return interrupt.New(stm32.IRQ_EXTI15_10, func(interrupt.Interrupt) { handlePinInterrupt(14) }) 224 case 15: 225 return interrupt.New(stm32.IRQ_EXTI15_10, func(interrupt.Interrupt) { handlePinInterrupt(15) }) 226 } 227 228 return interrupt.Interrupt{} 229 } 230 231 // -- SPI ---------------------------------------------------------------------- 232 233 type SPI struct { 234 Bus *stm32.SPI_Type 235 AltFuncSelector uint8 236 } 237 238 func (spi SPI) config8Bits() { 239 // Set rx threshold to 8-bits, so RXNE flag is set for 1 byte 240 // (common STM32 SPI implementation does 8-bit transfers only) 241 spi.Bus.CR2.SetBits(stm32.SPI_CR2_FRXTH) 242 } 243 244 func (spi SPI) configurePins(config SPIConfig) { 245 config.SCK.ConfigureAltFunc(PinConfig{Mode: PinModeSPICLK}, spi.AltFuncSelector) 246 config.SDO.ConfigureAltFunc(PinConfig{Mode: PinModeSPISDO}, spi.AltFuncSelector) 247 config.SDI.ConfigureAltFunc(PinConfig{Mode: PinModeSPISDI}, spi.AltFuncSelector) 248 } 249 250 func (spi SPI) getBaudRate(config SPIConfig) uint32 { 251 var clock uint32 252 253 // We keep this switch and separate management of SPI Clocks 254 // for future improvement of system/bus clocks and prescalers 255 switch spi.Bus { 256 case stm32.SPI1: 257 clock = CPUFrequency() 258 case stm32.SPI2, stm32.SPI3: 259 clock = CPUFrequency() 260 } 261 262 // limit requested frequency to bus frequency and min frequency (DIV256) 263 freq := config.Frequency 264 if min := clock / 256; freq < min { 265 freq = min 266 } else if freq > clock { 267 freq = clock 268 } 269 270 // calculate the exact clock divisor (freq=clock/div -> div=clock/freq). 271 // truncation is fine, since it produces a less-than-or-equal divisor, and 272 // thus a greater-than-or-equal frequency. 273 // divisors only come in consecutive powers of 2, so we can use log2 (or, 274 // equivalently, bits.Len - 1) to convert to respective enum value. 275 div := bits.Len32(clock/freq) - 1 276 277 // but DIV1 (2^0) is not permitted, as the least divisor is DIV2 (2^1), so 278 // subtract 1 from the log2 value, keeping a lower bound of 0 279 if div < 0 { 280 div = 0 281 } else if div > 0 { 282 div-- 283 } 284 285 // finally, shift the enumerated value into position for SPI CR1 286 return uint32(div) << stm32.SPI_CR1_BR_Pos 287 } 288 289 //---------- I2C related code 290 291 // Gets the value for TIMINGR register 292 func (i2c *I2C) getFreqRange() uint32 { 293 // This is a 'magic' value calculated by STM32CubeMX 294 // for 48Mhz PCLK1. 295 // TODO: Do calculations based on PCLK1 296 return 0x20303E5D 297 } 298 299 //---------- UART related code 300 301 // Configure the UART. 302 func (uart UART) configurePins(config UARTConfig) { 303 // enable the alternate functions on the TX and RX pins 304 config.TX.ConfigureAltFunc(PinConfig{Mode: PinModeUARTTX}, uart.TxAltFuncSelector) 305 config.RX.ConfigureAltFunc(PinConfig{Mode: PinModeUARTRX}, uart.RxAltFuncSelector) 306 } 307 308 // UART baudrate calc based on the bus and clockspeed 309 // NOTE: keep this in sync with the runtime/runtime_stm32wle5.go clock init code 310 func (uart *UART) getBaudRateDivisor(baudRate uint32) uint32 { 311 var br uint32 312 uartClock := CPUFrequency() // No Prescaler configuration 313 br = uint32((uartClock + baudRate/2) / baudRate) 314 return (br) 315 } 316 317 // Register names vary by ST processor, these are for STM L5 318 func (uart *UART) setRegisters() { 319 uart.rxReg = &uart.Bus.RDR 320 uart.txReg = &uart.Bus.TDR 321 uart.statusReg = &uart.Bus.ISR 322 uart.txEmptyFlag = stm32.USART_ISR_TXFNF //(TXFNF == TXE == bit 7, but depends alternate RM0461/1094) 323 } 324 325 //---------- Timer related code 326 327 var ( 328 TIM1 = TIM{ 329 EnableRegister: &stm32.RCC.APB2ENR, 330 EnableFlag: stm32.RCC_APB2ENR_TIM1EN, 331 Device: stm32.TIM1, 332 Channels: [4]TimerChannel{ 333 TimerChannel{Pins: []PinFunction{{PA8, AF1_TIM1_2_LPTIM1}}}, 334 TimerChannel{Pins: []PinFunction{{PA9, AF1_TIM1_2_LPTIM1}}}, 335 TimerChannel{Pins: []PinFunction{{PA10, AF1_TIM1_2_LPTIM1}}}, 336 TimerChannel{Pins: []PinFunction{{PA11, AF1_TIM1_2_LPTIM1}}}, 337 }, 338 busFreq: APB2_TIM_FREQ, 339 } 340 TIM2 = TIM{ 341 EnableRegister: &stm32.RCC.APB1ENR1, 342 EnableFlag: stm32.RCC_APB1ENR1_TIM2EN, 343 Device: stm32.TIM2, 344 Channels: [4]TimerChannel{ 345 TimerChannel{Pins: []PinFunction{{PA0, AF1_TIM1_2_LPTIM1}, {PA5, AF1_TIM1_2_LPTIM1}, {PA15, AF1_TIM1_2_LPTIM1}}}, 346 TimerChannel{Pins: []PinFunction{{PA1, AF1_TIM1_2_LPTIM1}, {PB3, AF1_TIM1_2_LPTIM1}}}, 347 TimerChannel{Pins: []PinFunction{{PA2, AF1_TIM1_2_LPTIM1}, {PB10, AF1_TIM1_2_LPTIM1}}}, 348 TimerChannel{Pins: []PinFunction{{PA3, AF1_TIM1_2_LPTIM1}, {PB11, AF1_TIM1_2_LPTIM1}}}, 349 }, 350 busFreq: APB1_TIM_FREQ, 351 } 352 TIM16 = TIM{ 353 EnableRegister: &stm32.RCC.APB2ENR, 354 EnableFlag: stm32.RCC_APB2ENR_TIM16EN, 355 Device: stm32.TIM16, 356 Channels: [4]TimerChannel{ 357 TimerChannel{Pins: []PinFunction{{PA6, AF14_TIM2_16_17_LPTIM2}}}, 358 TimerChannel{Pins: []PinFunction{}}, 359 TimerChannel{Pins: []PinFunction{}}, 360 TimerChannel{Pins: []PinFunction{}}, 361 }, 362 busFreq: APB2_TIM_FREQ, 363 } 364 TIM17 = TIM{ 365 EnableRegister: &stm32.RCC.APB2ENR, 366 EnableFlag: stm32.RCC_APB2ENR_TIM17EN, 367 Device: stm32.TIM17, 368 Channels: [4]TimerChannel{ 369 TimerChannel{Pins: []PinFunction{{PA7, AF1_TIM1_2_LPTIM1}, {PB9, AF1_TIM1_2_LPTIM1}}}, 370 TimerChannel{Pins: []PinFunction{}}, 371 TimerChannel{Pins: []PinFunction{}}, 372 TimerChannel{Pins: []PinFunction{}}, 373 }, 374 busFreq: APB2_TIM_FREQ, 375 } 376 ) 377 378 func (t *TIM) registerUPInterrupt() interrupt.Interrupt { 379 switch t { 380 case &TIM1: 381 return interrupt.New(stm32.IRQ_TIM1_UP, TIM1.handleUPInterrupt) 382 case &TIM2: 383 return interrupt.New(stm32.IRQ_TIM2, TIM2.handleUPInterrupt) 384 case &TIM16: 385 return interrupt.New(stm32.IRQ_TIM16, TIM16.handleUPInterrupt) 386 case &TIM17: 387 return interrupt.New(stm32.IRQ_TIM17, TIM17.handleUPInterrupt) 388 } 389 390 return interrupt.Interrupt{} 391 } 392 393 func (t *TIM) registerOCInterrupt() interrupt.Interrupt { 394 switch t { 395 case &TIM1: 396 return interrupt.New(stm32.IRQ_TIM1_CC, TIM1.handleOCInterrupt) 397 case &TIM2: 398 return interrupt.New(stm32.IRQ_TIM2, TIM2.handleOCInterrupt) 399 case &TIM16: 400 return interrupt.New(stm32.IRQ_TIM16, TIM16.handleOCInterrupt) 401 case &TIM17: 402 return interrupt.New(stm32.IRQ_TIM17, TIM17.handleOCInterrupt) 403 } 404 405 return interrupt.Interrupt{} 406 } 407 408 func (t *TIM) enableMainOutput() { 409 t.Device.BDTR.SetBits(stm32.TIM_BDTR_MOE) 410 } 411 412 func initRNG() { 413 stm32.RCC.AHB3ENR.SetBits(stm32.RCC_AHB3ENR_RNGEN) 414 415 // Enable RNG with config.A (See RM0453 22.6.2) 416 stm32.RNG.CR.Set(0x40F00D40) // RNG Config. A 417 stm32.RNG.HTCR.Set(0x17590ABC) // MAGIC NUMBER 418 stm32.RNG.HTCR.Set(0x0000AA74) // HTCR VALUE 419 stm32.RNG.CR.Set(0x00F00D4C) // CONFIG A + RNG_EN=1 + IE=1 420 } 421 422 //---------- 423 424 type arrtype = uint32 425 type arrRegType = volatile.Register32 426 427 const ( 428 ARR_MAX = 0x10000 429 PSC_MAX = 0x10000 430 ) 431 432 //---------- Flash related code 433 434 const eraseBlockSizeValue = 2048 435 436 // eraseBlock of the passed in block number 437 func eraseBlock(block uint32) error { 438 waitUntilFlashDone() 439 440 // check if operation is allowed. 441 if stm32.FLASH.GetSR_PESD() != 0 { 442 return errFlashCannotErasePage 443 } 444 445 // clear any previous errors 446 stm32.FLASH.SR.SetBits(0x3FA) 447 448 // page erase operation 449 stm32.FLASH.SetCR_PER(1) 450 defer stm32.FLASH.SetCR_PER(0) 451 452 // set the address to the page to be written 453 stm32.FLASH.SetCR_PNB(block) 454 defer stm32.FLASH.SetCR_PNB(0) 455 456 // start the page erase 457 stm32.FLASH.SetCR_STRT(1) 458 459 waitUntilFlashDone() 460 461 if err := checkError(); err != nil { 462 return err 463 } 464 465 return nil 466 } 467 468 const writeBlockSize = 8 469 470 func writeFlashData(address uintptr, data []byte) (int, error) { 471 if len(data)%writeBlockSize != 0 { 472 return 0, errFlashInvalidWriteLength 473 } 474 475 waitUntilFlashDone() 476 477 // check if operation is allowed 478 if stm32.FLASH.GetSR_PESD() != 0 { 479 return 0, errFlashNotAllowedWriteData 480 } 481 482 // clear any previous errors 483 stm32.FLASH.SR.SetBits(0x3FA) 484 485 for j := 0; j < len(data); j += writeBlockSize { 486 // start page write operation 487 stm32.FLASH.SetCR_PG(1) 488 489 // write first word using double-word high order word 490 *(*uint32)(unsafe.Pointer(address)) = binary.LittleEndian.Uint32(data[j : j+writeBlockSize/2]) 491 492 address += writeBlockSize / 2 493 494 // write second word using double-word low order word 495 *(*uint32)(unsafe.Pointer(address)) = binary.LittleEndian.Uint32(data[j+writeBlockSize/2 : j+writeBlockSize]) 496 497 waitUntilFlashDone() 498 499 if err := checkError(); err != nil { 500 return j, err 501 } 502 503 // end flash write 504 stm32.FLASH.SetCR_PG(0) 505 address += writeBlockSize / 2 506 } 507 508 return len(data), nil 509 } 510 511 func waitUntilFlashDone() { 512 for stm32.FLASH.GetSR_BSY() != 0 { 513 } 514 515 for stm32.FLASH.GetSR_CFGBSY() != 0 { 516 } 517 } 518 519 var ( 520 errFlashPGS = errors.New("errFlashPGS") 521 errFlashSIZE = errors.New("errFlashSIZE") 522 errFlashPGA = errors.New("errFlashPGA") 523 errFlashWRP = errors.New("errFlashWRP") 524 errFlashPROG = errors.New("errFlashPROG") 525 ) 526 527 func checkError() error { 528 switch { 529 case stm32.FLASH.GetSR_PGSERR() != 0: 530 return errFlashPGS 531 case stm32.FLASH.GetSR_SIZERR() != 0: 532 return errFlashSIZE 533 case stm32.FLASH.GetSR_PGAERR() != 0: 534 return errFlashPGA 535 case stm32.FLASH.GetSR_WRPERR() != 0: 536 return errFlashWRP 537 case stm32.FLASH.GetSR_PROGERR() != 0: 538 return errFlashPROG 539 } 540 541 return nil 542 }