github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/src/machine/machine_stm32l4.go (about) 1 //go:build stm32l4 2 3 package machine 4 5 import ( 6 "device/stm32" 7 "encoding/binary" 8 "errors" 9 "runtime/interrupt" 10 "runtime/volatile" 11 "unsafe" 12 ) 13 14 // Peripheral abstraction layer for the stm32l4 15 16 var deviceIDAddr = []uintptr{0x1FFF7590, 0x1FFF7594, 0x1FFF7598} 17 18 const ( 19 AF0_SYSTEM = 0 20 AF1_TIM1_2_LPTIM1 = 1 21 AF2_TIM1_2 = 2 22 AF3_USART2 = 3 23 AF4_I2C1_2_3 = 4 24 AF5_SPI1_2 = 5 25 AF6_SPI3 = 6 26 AF7_USART1_2_3 = 7 27 AF8_LPUART1 = 8 28 AF9_CAN1_TSC = 9 29 AF10_USB_QUADSPI = 10 30 AF12_COMP1_2_SWPMI1 = 12 31 AF13_SAI1 = 13 32 AF14_TIM2_15_16_LPTIM2 = 14 33 AF15_EVENTOUT = 15 34 ) 35 36 const ( 37 PA0 = portA + 0 38 PA1 = portA + 1 39 PA2 = portA + 2 40 PA3 = portA + 3 41 PA4 = portA + 4 42 PA5 = portA + 5 43 PA6 = portA + 6 44 PA7 = portA + 7 45 PA8 = portA + 8 46 PA9 = portA + 9 47 PA10 = portA + 10 48 PA11 = portA + 11 49 PA12 = portA + 12 50 PA13 = portA + 13 51 PA14 = portA + 14 52 PA15 = portA + 15 53 54 PB0 = portB + 0 55 PB1 = portB + 1 56 PB2 = portB + 2 57 PB3 = portB + 3 58 PB4 = portB + 4 59 PB5 = portB + 5 60 PB6 = portB + 6 61 PB7 = portB + 7 62 PB8 = portB + 8 63 PB9 = portB + 9 64 PB10 = portB + 10 65 PB11 = portB + 11 66 PB12 = portB + 12 67 PB13 = portB + 13 68 PB14 = portB + 14 69 PB15 = portB + 15 70 71 PC0 = portC + 0 72 PC1 = portC + 1 73 PC2 = portC + 2 74 PC3 = portC + 3 75 PC4 = portC + 4 76 PC5 = portC + 5 77 PC6 = portC + 6 78 PC7 = portC + 7 79 PC8 = portC + 8 80 PC9 = portC + 9 81 PC10 = portC + 10 82 PC11 = portC + 11 83 PC12 = portC + 12 84 PC13 = portC + 13 85 PC14 = portC + 14 86 PC15 = portC + 15 87 88 PD0 = portD + 0 89 PD1 = portD + 1 90 PD2 = portD + 2 91 PD3 = portD + 3 92 PD4 = portD + 4 93 PD5 = portD + 5 94 PD6 = portD + 6 95 PD7 = portD + 7 96 PD8 = portD + 8 97 PD9 = portD + 9 98 PD10 = portD + 10 99 PD11 = portD + 11 100 PD12 = portD + 12 101 PD13 = portD + 13 102 PD14 = portD + 14 103 PD15 = portD + 15 104 105 PE0 = portE + 0 106 PE1 = portE + 1 107 PE2 = portE + 2 108 PE3 = portE + 3 109 PE4 = portE + 4 110 PE5 = portE + 5 111 PE6 = portE + 6 112 PE7 = portE + 7 113 PE8 = portE + 8 114 PE9 = portE + 9 115 PE10 = portE + 10 116 PE11 = portE + 11 117 PE12 = portE + 12 118 PE13 = portE + 13 119 PE14 = portE + 14 120 PE15 = portE + 15 121 ) 122 123 // IRQs are defined here as they vary in the SVDs, but do have consistent mapping 124 // to Timer Interrupts. 125 const ( 126 irq_TIM1_BRK_TIM15 = 24 127 irq_TIM1_UP_TIM16 = 25 128 irq_TIM1_TRG_COM_TIM17 = 26 129 irq_TIM1_CC = 27 130 irq_TIM2 = 28 131 irq_TIM3 = 29 132 irq_TIM4 = 30 133 irq_TIM5 = 50 134 irq_TIM6 = 54 135 irq_TIM7 = 55 136 irq_TIM8_BRK = 43 137 irq_TIM8_UP = 44 138 irq_TIM8_TRG_COM = 45 139 irq_TIM8_CC = 46 140 ) 141 142 func (p Pin) getPort() *stm32.GPIO_Type { 143 switch p / 16 { 144 case 0: 145 return stm32.GPIOA 146 case 1: 147 return stm32.GPIOB 148 case 2: 149 return stm32.GPIOC 150 case 3: 151 return stm32.GPIOD 152 case 4: 153 return stm32.GPIOE 154 default: 155 panic("machine: unknown port") 156 } 157 } 158 159 // enableClock enables the clock for this desired GPIO port. 160 func (p Pin) enableClock() { 161 switch p / 16 { 162 case 0: 163 stm32.RCC.AHB2ENR.SetBits(stm32.RCC_AHB2ENR_GPIOAEN) 164 case 1: 165 stm32.RCC.AHB2ENR.SetBits(stm32.RCC_AHB2ENR_GPIOBEN) 166 case 2: 167 stm32.RCC.AHB2ENR.SetBits(stm32.RCC_AHB2ENR_GPIOCEN) 168 case 3: 169 stm32.RCC.AHB2ENR.SetBits(stm32.RCC_AHB2ENR_GPIODEN) 170 case 4: 171 stm32.RCC.AHB2ENR.SetBits(stm32.RCC_AHB2ENR_GPIOEEN) 172 default: 173 panic("machine: unknown port") 174 } 175 } 176 177 // Enable peripheral clock 178 func enableAltFuncClock(bus unsafe.Pointer) { 179 switch bus { 180 case unsafe.Pointer(stm32.PWR): // Power interface clock enable 181 stm32.RCC.APB1ENR1.SetBits(stm32.RCC_APB1ENR1_PWREN) 182 case unsafe.Pointer(stm32.I2C3): // I2C3 clock enable 183 stm32.RCC.APB1ENR1.SetBits(stm32.RCC_APB1ENR1_I2C3EN) 184 case unsafe.Pointer(stm32.I2C2): // I2C2 clock enable 185 stm32.RCC.APB1ENR1.SetBits(stm32.RCC_APB1ENR1_I2C2EN) 186 case unsafe.Pointer(stm32.I2C1): // I2C1 clock enable 187 stm32.RCC.APB1ENR1.SetBits(stm32.RCC_APB1ENR1_I2C1EN) 188 case unsafe.Pointer(stm32.UART4): // UART4 clock enable 189 stm32.RCC.APB1ENR1.SetBits(stm32.RCC_APB1ENR1_UART4EN) 190 case unsafe.Pointer(stm32.USART3): // USART3 clock enable 191 stm32.RCC.APB1ENR1.SetBits(stm32.RCC_APB1ENR1_USART3EN) 192 case unsafe.Pointer(stm32.USART2): // USART2 clock enable 193 stm32.RCC.APB1ENR1.SetBits(stm32.RCC_APB1ENR1_USART2EN) 194 case unsafe.Pointer(stm32.SPI3): // SPI3 clock enable 195 stm32.RCC.APB1ENR1.SetBits(stm32.RCC_APB1ENR1_SPI3EN) 196 case unsafe.Pointer(stm32.SPI2): // SPI2 clock enable 197 stm32.RCC.APB1ENR1.SetBits(stm32.RCC_APB1ENR1_SPI2EN) 198 case unsafe.Pointer(stm32.WWDG): // Window watchdog clock enable 199 stm32.RCC.APB1ENR1.SetBits(stm32.RCC_APB1ENR1_WWDGEN) 200 case unsafe.Pointer(stm32.TIM7): // TIM7 clock enable 201 stm32.RCC.APB1ENR1.SetBits(stm32.RCC_APB1ENR1_TIM7EN) 202 case unsafe.Pointer(stm32.TIM6): // TIM6 clock enable 203 stm32.RCC.APB1ENR1.SetBits(stm32.RCC_APB1ENR1_TIM6EN) 204 case unsafe.Pointer(stm32.TIM3): // TIM3 clock enable 205 stm32.RCC.APB1ENR1.SetBits(stm32.RCC_APB1ENR1_TIM3EN) 206 case unsafe.Pointer(stm32.TIM2): // TIM2 clock enable 207 stm32.RCC.APB1ENR1.SetBits(stm32.RCC_APB1ENR1_TIM2EN) 208 case unsafe.Pointer(stm32.LPTIM2): // LPTIM2 clock enable 209 stm32.RCC.APB1ENR2.SetBits(stm32.RCC_APB1ENR2_LPTIM2EN) 210 case unsafe.Pointer(stm32.LPUART1): // LPUART1 clock enable 211 stm32.RCC.APB1ENR2.SetBits(stm32.RCC_APB1ENR2_LPUART1EN) 212 case unsafe.Pointer(stm32.TIM16): // TIM16 clock enable 213 stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_TIM16EN) 214 case unsafe.Pointer(stm32.TIM15): // TIM15 clock enable 215 stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_TIM15EN) 216 case unsafe.Pointer(stm32.SYSCFG): // System configuration controller clock enable 217 stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_SYSCFGEN) 218 case unsafe.Pointer(stm32.SPI1): // SPI1 clock enable 219 stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_SPI1EN) 220 case unsafe.Pointer(stm32.USART1): // USART1 clock enable 221 stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_USART1EN) 222 case unsafe.Pointer(stm32.TIM1): // TIM1 clock enable 223 stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_TIM1EN) 224 } 225 } 226 227 func handlePinInterrupt(pin uint8) { 228 if stm32.EXTI.PR1.HasBits(1 << pin) { 229 // Writing 1 to the pending register clears the 230 // pending flag for that bit 231 stm32.EXTI.PR1.Set(1 << pin) 232 233 callback := pinCallbacks[pin] 234 if callback != nil { 235 callback(interruptPins[pin]) 236 } 237 } 238 } 239 240 func (p Pin) registerInterrupt() interrupt.Interrupt { 241 pin := uint8(p) % 16 242 243 switch pin { 244 case 0: 245 return interrupt.New(stm32.IRQ_EXTI0, func(interrupt.Interrupt) { handlePinInterrupt(0) }) 246 case 1: 247 return interrupt.New(stm32.IRQ_EXTI1, func(interrupt.Interrupt) { handlePinInterrupt(1) }) 248 case 2: 249 return interrupt.New(stm32.IRQ_EXTI2, func(interrupt.Interrupt) { handlePinInterrupt(2) }) 250 case 3: 251 return interrupt.New(stm32.IRQ_EXTI3, func(interrupt.Interrupt) { handlePinInterrupt(3) }) 252 case 4: 253 return interrupt.New(stm32.IRQ_EXTI4, func(interrupt.Interrupt) { handlePinInterrupt(4) }) 254 case 5: 255 return interrupt.New(stm32.IRQ_EXTI9_5, func(interrupt.Interrupt) { handlePinInterrupt(5) }) 256 case 6: 257 return interrupt.New(stm32.IRQ_EXTI9_5, func(interrupt.Interrupt) { handlePinInterrupt(6) }) 258 case 7: 259 return interrupt.New(stm32.IRQ_EXTI9_5, func(interrupt.Interrupt) { handlePinInterrupt(7) }) 260 case 8: 261 return interrupt.New(stm32.IRQ_EXTI9_5, func(interrupt.Interrupt) { handlePinInterrupt(8) }) 262 case 9: 263 return interrupt.New(stm32.IRQ_EXTI9_5, func(interrupt.Interrupt) { handlePinInterrupt(9) }) 264 case 10: 265 return interrupt.New(stm32.IRQ_EXTI15_10, func(interrupt.Interrupt) { handlePinInterrupt(10) }) 266 case 11: 267 return interrupt.New(stm32.IRQ_EXTI15_10, func(interrupt.Interrupt) { handlePinInterrupt(11) }) 268 case 12: 269 return interrupt.New(stm32.IRQ_EXTI15_10, func(interrupt.Interrupt) { handlePinInterrupt(12) }) 270 case 13: 271 return interrupt.New(stm32.IRQ_EXTI15_10, func(interrupt.Interrupt) { handlePinInterrupt(13) }) 272 case 14: 273 return interrupt.New(stm32.IRQ_EXTI15_10, func(interrupt.Interrupt) { handlePinInterrupt(14) }) 274 case 15: 275 return interrupt.New(stm32.IRQ_EXTI15_10, func(interrupt.Interrupt) { handlePinInterrupt(15) }) 276 } 277 278 return interrupt.Interrupt{} 279 } 280 281 //---------- UART related code 282 283 // Configure the UART. 284 func (uart *UART) configurePins(config UARTConfig) { 285 // enable the alternate functions on the TX and RX pins 286 config.TX.ConfigureAltFunc(PinConfig{Mode: PinModeUARTTX}, uart.TxAltFuncSelector) 287 config.RX.ConfigureAltFunc(PinConfig{Mode: PinModeUARTRX}, uart.RxAltFuncSelector) 288 } 289 290 // UART baudrate calc based on the bus and clockspeed 291 // NOTE: keep this in sync with the runtime/runtime_stm32l5x2.go clock init code 292 func (uart *UART) getBaudRateDivisor(baudRate uint32) uint32 { 293 return (CPUFrequency() / baudRate) 294 } 295 296 // Register names vary by ST processor, these are for STM L5 297 func (uart *UART) setRegisters() { 298 uart.rxReg = &uart.Bus.RDR 299 uart.txReg = &uart.Bus.TDR 300 uart.statusReg = &uart.Bus.ISR 301 uart.txEmptyFlag = stm32.USART_ISR_TXE 302 } 303 304 //---------- SPI related types and code 305 306 // SPI on the STM32Fxxx using MODER / alternate function pins 307 type SPI struct { 308 Bus *stm32.SPI_Type 309 AltFuncSelector uint8 310 } 311 312 func (spi SPI) config8Bits() { 313 // Set rx threshold to 8-bits, so RXNE flag is set for 1 byte 314 // (common STM32 SPI implementation does 8-bit transfers only) 315 spi.Bus.CR2.SetBits(stm32.SPI_CR2_FRXTH) 316 } 317 318 // Set baud rate for SPI 319 func (spi SPI) getBaudRate(config SPIConfig) uint32 { 320 var conf uint32 321 322 // Default 323 if config.Frequency == 0 { 324 config.Frequency = 4e6 325 } 326 327 localFrequency := config.Frequency 328 329 // set frequency dependent on PCLK prescaler. Since these are rather weird 330 // speeds due to the CPU freqency, pick a range up to that frquency for 331 // clients to use more human-understandable numbers, e.g. nearest 100KHz 332 333 // These are based on 80MHz peripheral clock frquency 334 switch { 335 case localFrequency < 312500: 336 conf = stm32.SPI_CR1_BR_Div256 337 case localFrequency < 625000: 338 conf = stm32.SPI_CR1_BR_Div128 339 case localFrequency < 1250000: 340 conf = stm32.SPI_CR1_BR_Div64 341 case localFrequency < 2500000: 342 conf = stm32.SPI_CR1_BR_Div32 343 case localFrequency < 5000000: 344 conf = stm32.SPI_CR1_BR_Div16 345 case localFrequency < 10000000: 346 conf = stm32.SPI_CR1_BR_Div8 347 // NOTE: many SPI components won't operate reliably (or at all) above 10MHz 348 // Check the datasheet of the part 349 case localFrequency < 20000000: 350 conf = stm32.SPI_CR1_BR_Div4 351 case localFrequency < 40000000: 352 conf = stm32.SPI_CR1_BR_Div2 353 default: 354 // None of the specific baudrates were selected; choose the lowest speed 355 conf = stm32.SPI_CR1_BR_Div256 356 } 357 358 return conf << stm32.SPI_CR1_BR_Pos 359 } 360 361 // Configure SPI pins for input output and clock 362 func (spi SPI) configurePins(config SPIConfig) { 363 config.SCK.ConfigureAltFunc(PinConfig{Mode: PinModeSPICLK}, spi.AltFuncSelector) 364 config.SDO.ConfigureAltFunc(PinConfig{Mode: PinModeSPISDO}, spi.AltFuncSelector) 365 config.SDI.ConfigureAltFunc(PinConfig{Mode: PinModeSPISDI}, spi.AltFuncSelector) 366 } 367 368 //---------- Timer related code 369 370 var ( 371 TIM1 = TIM{ 372 EnableRegister: &stm32.RCC.APB2ENR, 373 EnableFlag: stm32.RCC_APB2ENR_TIM1EN, 374 Device: stm32.TIM1, 375 Channels: [4]TimerChannel{ 376 TimerChannel{Pins: []PinFunction{ 377 {PA8, AF1_TIM1_2_LPTIM1}, 378 }}, 379 TimerChannel{Pins: []PinFunction{ 380 {PA9, AF1_TIM1_2_LPTIM1}, 381 }}, 382 TimerChannel{Pins: []PinFunction{ 383 {PA10, AF1_TIM1_2_LPTIM1}, 384 }}, 385 TimerChannel{Pins: []PinFunction{ 386 {PA11, AF1_TIM1_2_LPTIM1}, 387 }}, 388 }, 389 busFreq: APB2_TIM_FREQ, 390 } 391 392 TIM2 = TIM{ 393 EnableRegister: &stm32.RCC.APB1ENR1, 394 EnableFlag: stm32.RCC_APB1ENR1_TIM2EN, 395 Device: stm32.TIM2, 396 Channels: [4]TimerChannel{ 397 TimerChannel{Pins: []PinFunction{ 398 {PA0, AF1_TIM1_2_LPTIM1}, 399 {PA5, AF1_TIM1_2_LPTIM1}, 400 {PA15, AF1_TIM1_2_LPTIM1}, 401 }}, 402 TimerChannel{Pins: []PinFunction{ 403 {PA1, AF1_TIM1_2_LPTIM1}, 404 {PB3, AF1_TIM1_2_LPTIM1}, 405 }}, 406 TimerChannel{Pins: []PinFunction{ 407 {PA2, AF1_TIM1_2_LPTIM1}, 408 }}, 409 TimerChannel{Pins: []PinFunction{ 410 {PA3, AF1_TIM1_2_LPTIM1}, 411 }}, 412 }, 413 busFreq: APB1_TIM_FREQ, 414 } 415 416 TIM3 = TIM{ 417 EnableRegister: &stm32.RCC.APB1ENR1, 418 EnableFlag: stm32.RCC_APB1ENR1_TIM3EN, 419 Device: stm32.TIM3, 420 Channels: [4]TimerChannel{ 421 TimerChannel{Pins: []PinFunction{}}, 422 TimerChannel{Pins: []PinFunction{}}, 423 TimerChannel{Pins: []PinFunction{}}, 424 TimerChannel{Pins: []PinFunction{}}, 425 }, 426 busFreq: APB1_TIM_FREQ, 427 } 428 429 TIM6 = TIM{ 430 EnableRegister: &stm32.RCC.APB1ENR1, 431 EnableFlag: stm32.RCC_APB1ENR1_TIM6EN, 432 Device: stm32.TIM6, 433 Channels: [4]TimerChannel{ 434 TimerChannel{Pins: []PinFunction{}}, 435 TimerChannel{Pins: []PinFunction{}}, 436 TimerChannel{Pins: []PinFunction{}}, 437 TimerChannel{Pins: []PinFunction{}}, 438 }, 439 busFreq: APB1_TIM_FREQ, 440 } 441 442 TIM7 = TIM{ 443 EnableRegister: &stm32.RCC.APB1ENR1, 444 EnableFlag: stm32.RCC_APB1ENR1_TIM7EN, 445 Device: stm32.TIM7, 446 Channels: [4]TimerChannel{ 447 TimerChannel{Pins: []PinFunction{}}, 448 TimerChannel{Pins: []PinFunction{}}, 449 TimerChannel{Pins: []PinFunction{}}, 450 TimerChannel{Pins: []PinFunction{}}, 451 }, 452 busFreq: APB1_TIM_FREQ, 453 } 454 455 TIM15 = TIM{ 456 EnableRegister: &stm32.RCC.APB2ENR, 457 EnableFlag: stm32.RCC_APB2ENR_TIM15EN, 458 Device: stm32.TIM15, 459 Channels: [4]TimerChannel{ 460 TimerChannel{Pins: []PinFunction{ 461 {PA2, AF14_TIM2_15_16_LPTIM2}, 462 }}, 463 TimerChannel{Pins: []PinFunction{ 464 {PA3, AF14_TIM2_15_16_LPTIM2}, 465 }}, 466 TimerChannel{Pins: []PinFunction{}}, 467 TimerChannel{Pins: []PinFunction{}}, 468 }, 469 busFreq: APB2_TIM_FREQ, 470 } 471 472 TIM16 = TIM{ 473 EnableRegister: &stm32.RCC.APB2ENR, 474 EnableFlag: stm32.RCC_APB2ENR_TIM16EN, 475 Device: stm32.TIM16, 476 Channels: [4]TimerChannel{ 477 TimerChannel{Pins: []PinFunction{ 478 {PA6, AF14_TIM2_15_16_LPTIM2}, 479 }}, 480 TimerChannel{Pins: []PinFunction{}}, 481 TimerChannel{Pins: []PinFunction{}}, 482 TimerChannel{Pins: []PinFunction{}}, 483 }, 484 busFreq: APB2_TIM_FREQ, 485 } 486 ) 487 488 func (t *TIM) registerUPInterrupt() interrupt.Interrupt { 489 switch t { 490 case &TIM1: 491 return interrupt.New(irq_TIM1_UP_TIM16, TIM1.handleUPInterrupt) 492 case &TIM2: 493 return interrupt.New(irq_TIM2, TIM2.handleUPInterrupt) 494 case &TIM3: 495 return interrupt.New(irq_TIM3, TIM3.handleUPInterrupt) 496 case &TIM6: 497 return interrupt.New(irq_TIM6, TIM6.handleUPInterrupt) 498 case &TIM7: 499 return interrupt.New(irq_TIM7, TIM7.handleUPInterrupt) 500 case &TIM15: 501 return interrupt.New(irq_TIM1_BRK_TIM15, TIM15.handleUPInterrupt) 502 case &TIM16: 503 return interrupt.New(irq_TIM1_UP_TIM16, TIM16.handleUPInterrupt) 504 } 505 506 return interrupt.Interrupt{} 507 } 508 509 func (t *TIM) registerOCInterrupt() interrupt.Interrupt { 510 switch t { 511 case &TIM1: 512 return interrupt.New(irq_TIM1_CC, TIM1.handleUPInterrupt) 513 case &TIM2: 514 return interrupt.New(irq_TIM2, TIM2.handleOCInterrupt) 515 case &TIM3: 516 return interrupt.New(irq_TIM3, TIM3.handleOCInterrupt) 517 case &TIM6: 518 return interrupt.New(irq_TIM6, TIM6.handleOCInterrupt) 519 case &TIM7: 520 return interrupt.New(irq_TIM7, TIM7.handleOCInterrupt) 521 case &TIM15: 522 return interrupt.New(irq_TIM1_BRK_TIM15, TIM15.handleOCInterrupt) 523 case &TIM16: 524 return interrupt.New(irq_TIM1_UP_TIM16, TIM16.handleOCInterrupt) 525 } 526 527 return interrupt.Interrupt{} 528 } 529 530 func (t *TIM) enableMainOutput() { 531 // nothing to do - no BDTR register 532 } 533 534 type arrtype = uint32 535 type arrRegType = volatile.Register32 536 537 const ( 538 ARR_MAX = 0x10000 539 PSC_MAX = 0x10000 540 ) 541 542 func initRNG() { 543 stm32.RCC.CRRCR.SetBits(stm32.RCC_CRRCR_HSI48ON) 544 for !stm32.RCC.CRRCR.HasBits(stm32.RCC_CRRCR_HSI48RDY) { 545 } 546 547 stm32.RCC.AHB2ENR.SetBits(stm32.RCC_AHB2ENR_RNGEN) 548 stm32.RNG.CR.SetBits(stm32.RNG_CR_RNGEN) 549 } 550 551 //---------- Flash related code 552 553 const eraseBlockSizeValue = 2048 554 555 // see RM0394 page 83 556 // eraseBlock of the passed in block number 557 func eraseBlock(block uint32) error { 558 waitUntilFlashDone() 559 560 // clear any previous errors 561 stm32.FLASH.SR.SetBits(0x3FA) 562 563 // page erase operation 564 stm32.FLASH.SetCR_PER(1) 565 defer stm32.FLASH.SetCR_PER(0) 566 567 // set the page to be erased 568 stm32.FLASH.SetCR_PNB(block) 569 570 // start the page erase 571 stm32.FLASH.SetCR_START(1) 572 573 waitUntilFlashDone() 574 575 if err := checkError(); err != nil { 576 return err 577 } 578 579 return nil 580 } 581 582 const writeBlockSize = 8 583 584 // see RM0394 page 84 585 // It is only possible to program double word (2 x 32-bit data). 586 func writeFlashData(address uintptr, data []byte) (int, error) { 587 if len(data)%writeBlockSize != 0 { 588 return 0, errFlashInvalidWriteLength 589 } 590 591 waitUntilFlashDone() 592 593 // clear any previous errors 594 stm32.FLASH.SR.SetBits(0x3FA) 595 596 for j := 0; j < len(data); j += writeBlockSize { 597 // start page write operation 598 stm32.FLASH.SetCR_PG(1) 599 600 // write second word using double-word high order word 601 *(*uint32)(unsafe.Pointer(address)) = binary.LittleEndian.Uint32(data[j : j+writeBlockSize/2]) 602 603 address += writeBlockSize / 2 604 605 // write first word using double-word low order word 606 *(*uint32)(unsafe.Pointer(address)) = binary.LittleEndian.Uint32(data[j+writeBlockSize/2 : j+writeBlockSize]) 607 608 waitUntilFlashDone() 609 610 if err := checkError(); err != nil { 611 return j, err 612 } 613 614 // end flash write 615 stm32.FLASH.SetCR_PG(0) 616 address += writeBlockSize / 2 617 } 618 619 return len(data), nil 620 } 621 622 func waitUntilFlashDone() { 623 for stm32.FLASH.GetSR_BSY() != 0 { 624 } 625 } 626 627 var ( 628 errFlashPGS = errors.New("errFlashPGS") 629 errFlashSIZE = errors.New("errFlashSIZE") 630 errFlashPGA = errors.New("errFlashPGA") 631 errFlashWRP = errors.New("errFlashWRP") 632 errFlashPROG = errors.New("errFlashPROG") 633 ) 634 635 func checkError() error { 636 switch { 637 case stm32.FLASH.GetSR_PGSERR() != 0: 638 return errFlashPGS 639 case stm32.FLASH.GetSR_SIZERR() != 0: 640 return errFlashSIZE 641 case stm32.FLASH.GetSR_PGAERR() != 0: 642 return errFlashPGA 643 case stm32.FLASH.GetSR_WRPERR() != 0: 644 return errFlashWRP 645 case stm32.FLASH.GetSR_PROGERR() != 0: 646 return errFlashPROG 647 } 648 649 return nil 650 }