github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/src/machine/machine_esp32c3.go (about) 1 //go:build esp32c3 2 3 package machine 4 5 import ( 6 "device/esp" 7 "device/riscv" 8 "errors" 9 "runtime/interrupt" 10 "runtime/volatile" 11 "sync" 12 "unsafe" 13 ) 14 15 const deviceName = esp.Device 16 const maxPin = 22 17 const cpuInterruptFromPin = 6 18 19 // CPUFrequency returns the current CPU frequency of the chip. 20 // Currently it is a fixed frequency but it may allow changing in the future. 21 func CPUFrequency() uint32 { 22 return 160e6 // 160MHz 23 } 24 25 const ( 26 PinOutput PinMode = iota 27 PinInput 28 PinInputPullup 29 PinInputPulldown 30 ) 31 32 const ( 33 GPIO0 Pin = 0 34 GPIO1 Pin = 1 35 GPIO2 Pin = 2 36 GPIO3 Pin = 3 37 GPIO4 Pin = 4 38 GPIO5 Pin = 5 39 GPIO6 Pin = 6 40 GPIO7 Pin = 7 41 GPIO8 Pin = 8 42 GPIO9 Pin = 9 43 GPIO10 Pin = 10 44 GPIO11 Pin = 11 45 GPIO12 Pin = 12 46 GPIO13 Pin = 13 47 GPIO14 Pin = 14 48 GPIO15 Pin = 15 49 GPIO16 Pin = 16 50 GPIO17 Pin = 17 51 GPIO18 Pin = 18 52 GPIO19 Pin = 19 53 GPIO20 Pin = 20 54 GPIO21 Pin = 21 55 ) 56 57 type PinChange uint8 58 59 // Pin change interrupt constants for SetInterrupt. 60 const ( 61 PinRising PinChange = iota + 1 62 PinFalling 63 PinToggle 64 ) 65 66 // Configure this pin with the given configuration. 67 func (p Pin) Configure(config PinConfig) { 68 if p == NoPin { 69 // This simplifies pin configuration in peripherals such as SPI. 70 return 71 } 72 73 var muxConfig uint32 74 75 // Configure this pin as a GPIO pin. 76 const function = 1 // function 1 is GPIO for every pin 77 muxConfig |= function << esp.IO_MUX_GPIO_MCU_SEL_Pos 78 79 // Make this pin an input pin (always). 80 muxConfig |= esp.IO_MUX_GPIO_FUN_IE 81 82 // Set drive strength: 0 is lowest, 3 is highest. 83 muxConfig |= 2 << esp.IO_MUX_GPIO_FUN_DRV_Pos 84 85 // Select pull mode. 86 if config.Mode == PinInputPullup { 87 muxConfig |= esp.IO_MUX_GPIO_FUN_WPU 88 } else if config.Mode == PinInputPulldown { 89 muxConfig |= esp.IO_MUX_GPIO_FUN_WPD 90 } 91 92 // Configure the pad with the given IO mux configuration. 93 p.mux().Set(muxConfig) 94 95 // Set the output signal to the simple GPIO output. 96 p.outFunc().Set(0x80) 97 98 switch config.Mode { 99 case PinOutput: 100 // Set the 'output enable' bit. 101 esp.GPIO.ENABLE_W1TS.Set(1 << p) 102 case PinInput, PinInputPullup, PinInputPulldown: 103 // Clear the 'output enable' bit. 104 esp.GPIO.ENABLE_W1TC.Set(1 << p) 105 } 106 } 107 108 // outFunc returns the FUNCx_OUT_SEL_CFG register used for configuring the 109 // output function selection. 110 func (p Pin) outFunc() *volatile.Register32 { 111 return (*volatile.Register32)(unsafe.Add(unsafe.Pointer(&esp.GPIO.FUNC0_OUT_SEL_CFG), uintptr(p)*4)) 112 } 113 114 func (p Pin) pinReg() *volatile.Register32 { 115 return (*volatile.Register32)(unsafe.Pointer((uintptr(unsafe.Pointer(&esp.GPIO.PIN0)) + uintptr(p)*4))) 116 } 117 118 // inFunc returns the FUNCy_IN_SEL_CFG register used for configuring the input 119 // function selection. 120 func inFunc(signal uint32) *volatile.Register32 { 121 return (*volatile.Register32)(unsafe.Add(unsafe.Pointer(&esp.GPIO.FUNC0_IN_SEL_CFG), uintptr(signal)*4)) 122 } 123 124 // mux returns the I/O mux configuration register corresponding to the given 125 // GPIO pin. 126 func (p Pin) mux() *volatile.Register32 { 127 return (*volatile.Register32)(unsafe.Add(unsafe.Pointer(&esp.IO_MUX.GPIO0), uintptr(p)*4)) 128 } 129 130 // pin returns the PIN register corresponding to the given GPIO pin. 131 func (p Pin) pin() *volatile.Register32 { 132 return (*volatile.Register32)(unsafe.Add(unsafe.Pointer(&esp.GPIO.PIN0), uintptr(p)*4)) 133 } 134 135 // Set the pin to high or low. 136 // Warning: only use this on an output pin! 137 func (p Pin) Set(value bool) { 138 if value { 139 reg, mask := p.portMaskSet() 140 reg.Set(mask) 141 } else { 142 reg, mask := p.portMaskClear() 143 reg.Set(mask) 144 } 145 } 146 147 // Get returns the current value of a GPIO pin when configured as an input or as 148 // an output. 149 func (p Pin) Get() bool { 150 reg := &esp.GPIO.IN 151 return (reg.Get()>>p)&1 > 0 152 } 153 154 // Return the register and mask to enable a given GPIO pin. This can be used to 155 // implement bit-banged drivers. 156 // 157 // Warning: only use this on an output pin! 158 func (p Pin) PortMaskSet() (*uint32, uint32) { 159 reg, mask := p.portMaskSet() 160 return ®.Reg, mask 161 } 162 163 // Return the register and mask to disable a given GPIO pin. This can be used to 164 // implement bit-banged drivers. 165 // 166 // Warning: only use this on an output pin! 167 func (p Pin) PortMaskClear() (*uint32, uint32) { 168 reg, mask := p.portMaskClear() 169 return ®.Reg, mask 170 } 171 172 func (p Pin) portMaskSet() (*volatile.Register32, uint32) { 173 return &esp.GPIO.OUT_W1TS, 1 << p 174 } 175 176 func (p Pin) portMaskClear() (*volatile.Register32, uint32) { 177 return &esp.GPIO.OUT_W1TC, 1 << p 178 } 179 180 // SetInterrupt sets an interrupt to be executed when a particular pin changes 181 // state. The pin should already be configured as an input, including a pull up 182 // or down if no external pull is provided. 183 // 184 // You can pass a nil func to unset the pin change interrupt. If you do so, 185 // the change parameter is ignored and can be set to any value (such as 0). 186 // If the pin is already configured with a callback, you must first unset 187 // this pins interrupt before you can set a new callback. 188 func (p Pin) SetInterrupt(change PinChange, callback func(Pin)) (err error) { 189 if p >= maxPin { 190 return ErrInvalidInputPin 191 } 192 193 if callback == nil { 194 // Disable this pin interrupt 195 p.pin().ClearBits(esp.GPIO_PIN_INT_TYPE_Msk | esp.GPIO_PIN_INT_ENA_Msk) 196 197 if pinCallbacks[p] != nil { 198 pinCallbacks[p] = nil 199 } 200 return nil 201 } 202 203 if pinCallbacks[p] != nil { 204 // The pin was already configured. 205 // To properly re-configure a pin, unset it first and set a new 206 // configuration. 207 return ErrNoPinChangeChannel 208 } 209 pinCallbacks[p] = callback 210 211 onceSetupPinInterrupt.Do(func() { 212 err = setupPinInterrupt() 213 }) 214 if err != nil { 215 return err 216 } 217 218 p.pin().Set( 219 (p.pin().Get() & ^uint32(esp.GPIO_PIN_INT_TYPE_Msk|esp.GPIO_PIN_INT_ENA_Msk)) | 220 uint32(change)<<esp.GPIO_PIN_INT_TYPE_Pos | uint32(1)<<esp.GPIO_PIN_INT_ENA_Pos) 221 222 return nil 223 } 224 225 var ( 226 pinCallbacks [maxPin]func(Pin) 227 onceSetupPinInterrupt sync.Once 228 ) 229 230 func setupPinInterrupt() error { 231 esp.INTERRUPT_CORE0.GPIO_INTERRUPT_PRO_MAP.Set(cpuInterruptFromPin) 232 return interrupt.New(cpuInterruptFromPin, func(interrupt.Interrupt) { 233 status := esp.GPIO.STATUS.Get() 234 for i, mask := 0, uint32(1); i < maxPin; i, mask = i+1, mask<<1 { 235 if (status&mask) != 0 && pinCallbacks[i] != nil { 236 pinCallbacks[i](Pin(i)) 237 } 238 } 239 // clear interrupt bit 240 esp.GPIO.STATUS_W1TC.SetBits(status) 241 }).Enable() 242 } 243 244 var ( 245 DefaultUART = UART0 246 247 UART0 = &_UART0 248 _UART0 = UART{Bus: esp.UART0, Buffer: NewRingBuffer()} 249 UART1 = &_UART1 250 _UART1 = UART{Bus: esp.UART1, Buffer: NewRingBuffer()} 251 252 onceUart = sync.Once{} 253 errSamePins = errors.New("UART: invalid pin combination") 254 errWrongUART = errors.New("UART: unsupported UARTn") 255 errWrongBitSize = errors.New("UART: invalid data size") 256 errWrongStopBitSize = errors.New("UART: invalid bit size") 257 ) 258 259 type UART struct { 260 Bus *esp.UART_Type 261 Buffer *RingBuffer 262 ParityErrorDetected bool // set when parity error detected 263 DataErrorDetected bool // set when data corruption detected 264 DataOverflowDetected bool // set when data overflow detected in UART FIFO buffer or RingBuffer 265 } 266 267 const ( 268 defaultDataBits = 8 269 defaultStopBit = 1 270 defaultParity = ParityNone 271 272 uartInterrupts = esp.UART_INT_ENA_RXFIFO_FULL_INT_ENA | 273 esp.UART_INT_ENA_PARITY_ERR_INT_ENA | 274 esp.UART_INT_ENA_FRM_ERR_INT_ENA | 275 esp.UART_INT_ENA_RXFIFO_OVF_INT_ENA | 276 esp.UART_INT_ENA_GLITCH_DET_INT_ENA 277 278 pplClockFreq = 80e6 279 ) 280 281 type registerSet struct { 282 interruptMapReg *volatile.Register32 283 uartClockBitMask uint32 284 gpioMatrixSignal uint32 285 } 286 287 func (uart *UART) Configure(config UARTConfig) error { 288 if config.BaudRate == 0 { 289 config.BaudRate = 115200 290 } 291 if config.TX == config.RX { 292 return errSamePins 293 } 294 switch { 295 case uart.Bus == esp.UART0: 296 return uart.configure(config, registerSet{ 297 interruptMapReg: &esp.INTERRUPT_CORE0.UART_INTR_MAP, 298 uartClockBitMask: esp.SYSTEM_PERIP_CLK_EN0_UART_CLK_EN, 299 gpioMatrixSignal: 6, 300 }) 301 case uart.Bus == esp.UART1: 302 return uart.configure(config, registerSet{ 303 interruptMapReg: &esp.INTERRUPT_CORE0.UART1_INTR_MAP, 304 uartClockBitMask: esp.SYSTEM_PERIP_CLK_EN0_UART1_CLK_EN, 305 gpioMatrixSignal: 9, 306 }) 307 } 308 return errWrongUART 309 } 310 311 func (uart *UART) configure(config UARTConfig, regs registerSet) error { 312 313 initUARTClock(uart.Bus, regs) 314 315 // - disbale TX/RX clock to make sure the UART transmitter or receiver is not at work during configuration 316 uart.Bus.SetCLK_CONF_TX_SCLK_EN(0) 317 uart.Bus.SetCLK_CONF_RX_SCLK_EN(0) 318 319 // Configure static registers (Ref: Configuring URATn Communication) 320 321 // - default clock source: 1=APB_CLK, 2=FOSC_CLK, 3=XTAL_CLK 322 uart.Bus.SetCLK_CONF_SCLK_SEL(1) 323 // reset divisor of the divider via UART_SCLK_DIV_NUM, UART_SCLK_DIV_A, and UART_SCLK_DIV_B 324 uart.Bus.SetCLK_CONF_SCLK_DIV_NUM(0) 325 uart.Bus.SetCLK_CONF_SCLK_DIV_A(0) 326 uart.Bus.SetCLK_CONF_SCLK_DIV_B(0) 327 328 // - the baud rate 329 uart.SetBaudRate(config.BaudRate) 330 // - the data format 331 uart.SetFormat(defaultDataBits, defaultStopBit, defaultParity) 332 // - set UART mode 333 uart.Bus.SetRS485_CONF_RS485_EN(0) 334 uart.Bus.SetRS485_CONF_RS485TX_RX_EN(0) 335 uart.Bus.SetRS485_CONF_RS485RXBY_TX_EN(0) 336 uart.Bus.SetCONF0_IRDA_EN(0) 337 // - disable hw-flow control 338 uart.Bus.SetCONF0_TX_FLOW_EN(0) 339 uart.Bus.SetCONF1_RX_FLOW_EN(0) 340 341 // synchronize values into Core Clock 342 uart.Bus.SetID_REG_UPDATE(1) 343 344 uart.setupPins(config, regs) 345 uart.configureInterrupt(regs.interruptMapReg) 346 uart.enableTransmitter() 347 uart.enableReceiver() 348 349 // Start TX/RX 350 uart.Bus.SetCLK_CONF_TX_SCLK_EN(1) 351 uart.Bus.SetCLK_CONF_RX_SCLK_EN(1) 352 return nil 353 } 354 355 func (uart *UART) SetFormat(dataBits, stopBits int, parity UARTParity) error { 356 if dataBits < 5 { 357 return errWrongBitSize 358 } 359 if stopBits > 1 { 360 return errWrongStopBitSize 361 } 362 // - data length 363 uart.Bus.SetCONF0_BIT_NUM(uint32(dataBits - 5)) 364 // - stop bit 365 uart.Bus.SetCONF0_STOP_BIT_NUM(uint32(stopBits)) 366 // - parity check 367 switch parity { 368 case ParityNone: 369 uart.Bus.SetCONF0_PARITY_EN(0) 370 case ParityEven: 371 uart.Bus.SetCONF0_PARITY_EN(1) 372 uart.Bus.SetCONF0_PARITY(0) 373 case ParityOdd: 374 uart.Bus.SetCONF0_PARITY_EN(1) 375 uart.Bus.SetCONF0_PARITY(1) 376 } 377 return nil 378 } 379 380 func initUARTClock(bus *esp.UART_Type, regs registerSet) { 381 uartClock := &esp.SYSTEM.PERIP_CLK_EN0 382 uartClockReset := &esp.SYSTEM.PERIP_RST_EN0 383 384 // Initialize/reset URATn (Ref: Initializing URATn) 385 // - enable the clock for UART RAM 386 uartClock.SetBits(esp.SYSTEM_PERIP_CLK_EN0_UART_MEM_CLK_EN) 387 // - enable APB_CLK for UARTn 388 uartClock.SetBits(regs.uartClockBitMask) 389 // - reset sequence 390 uartClockReset.ClearBits(regs.uartClockBitMask) 391 bus.SetCLK_CONF_RST_CORE(1) 392 uartClockReset.SetBits(regs.uartClockBitMask) 393 uartClockReset.ClearBits(regs.uartClockBitMask) 394 bus.SetCLK_CONF_RST_CORE(0) 395 // synchronize core register 396 bus.SetID_REG_UPDATE(0) 397 // enable RTC clock 398 esp.RTC_CNTL.SetCLK_CONF_DIG_CLK8M_EN(1) 399 // wait for Core Clock to ready for configuration 400 for bus.GetID_REG_UPDATE() > 0 { 401 riscv.Asm("nop") 402 } 403 } 404 405 func (uart *UART) SetBaudRate(baudRate uint32) { 406 // based on esp-idf 407 max_div := uint32((1 << 12) - 1) 408 sclk_div := (pplClockFreq + (max_div * baudRate) - 1) / (max_div * baudRate) 409 clk_div := (pplClockFreq << 4) / (baudRate * sclk_div) 410 uart.Bus.SetCLKDIV(clk_div >> 4) 411 uart.Bus.SetCLKDIV_FRAG(clk_div & 0xf) 412 uart.Bus.SetCLK_CONF_SCLK_DIV_NUM(sclk_div - 1) 413 } 414 415 func (uart *UART) setupPins(config UARTConfig, regs registerSet) { 416 config.RX.Configure(PinConfig{Mode: PinInputPullup}) 417 config.TX.Configure(PinConfig{Mode: PinInputPullup}) 418 419 // link TX with GPIO signal X (technical reference manual 5.10) (this is not interrupt signal!) 420 config.TX.outFunc().Set(regs.gpioMatrixSignal) 421 // link RX with GPIO signal X and route signals via GPIO matrix (GPIO_SIGn_IN_SEL 0x40) 422 inFunc(regs.gpioMatrixSignal).Set(esp.GPIO_FUNC_IN_SEL_CFG_SEL | uint32(config.RX)) 423 } 424 425 func (uart *UART) configureInterrupt(intrMapReg *volatile.Register32) { // Disable all UART interrupts 426 // Disable all UART interrupts 427 uart.Bus.INT_ENA.ClearBits(0x0ffff) 428 429 intrMapReg.Set(7) 430 onceUart.Do(func() { 431 _ = interrupt.New(7, func(i interrupt.Interrupt) { 432 UART0.serveInterrupt(0) 433 UART1.serveInterrupt(1) 434 }).Enable() 435 }) 436 } 437 438 func (uart *UART) serveInterrupt(num int) { 439 // get interrupt status 440 interrutFlag := uart.Bus.INT_ST.Get() 441 if (interrutFlag & uartInterrupts) == 0 { 442 return 443 } 444 445 // block UART interrupts while processing 446 uart.Bus.INT_ENA.ClearBits(uartInterrupts) 447 448 if interrutFlag&esp.UART_INT_ENA_RXFIFO_FULL_INT_ENA > 0 { 449 for uart.Bus.GetSTATUS_RXFIFO_CNT() > 0 { 450 b := uart.Bus.GetFIFO_RXFIFO_RD_BYTE() 451 if !uart.Buffer.Put(byte(b & 0xff)) { 452 uart.DataOverflowDetected = true 453 } 454 } 455 } 456 if interrutFlag&esp.UART_INT_ENA_PARITY_ERR_INT_ENA > 0 { 457 uart.ParityErrorDetected = true 458 } 459 if 0 != interrutFlag&esp.UART_INT_ENA_FRM_ERR_INT_ENA { 460 uart.DataErrorDetected = true 461 } 462 if 0 != interrutFlag&esp.UART_INT_ENA_RXFIFO_OVF_INT_ENA { 463 uart.DataOverflowDetected = true 464 } 465 if 0 != interrutFlag&esp.UART_INT_ENA_GLITCH_DET_INT_ENA { 466 uart.DataErrorDetected = true 467 } 468 469 // Clear the UART interrupt status 470 uart.Bus.INT_CLR.SetBits(interrutFlag) 471 uart.Bus.INT_CLR.ClearBits(interrutFlag) 472 // Enable interrupts 473 uart.Bus.INT_ENA.Set(uartInterrupts) 474 } 475 476 const uart_empty_thresh_default = 10 477 478 func (uart *UART) enableTransmitter() { 479 uart.Bus.SetCONF0_TXFIFO_RST(1) 480 uart.Bus.SetCONF0_TXFIFO_RST(0) 481 // TXINFO empty threshold is when txfifo_empty_int interrupt produced after the amount of data in Tx-FIFO is less than this register value. 482 uart.Bus.SetCONF1_TXFIFO_EMPTY_THRHD(uart_empty_thresh_default) 483 // we are not using interrut on TX since write we are waiting for FIFO to have space. 484 // uart.Bus.INT_ENA.SetBits(esp.UART_INT_ENA_TXFIFO_EMPTY_INT_ENA) 485 } 486 487 func (uart *UART) enableReceiver() { 488 uart.Bus.SetCONF0_RXFIFO_RST(1) 489 uart.Bus.SetCONF0_RXFIFO_RST(0) 490 // using value 1 so that we can start populate ring buffer with data as we get it 491 uart.Bus.SetCONF1_RXFIFO_FULL_THRHD(1) 492 // enable interrupts for: 493 uart.Bus.SetINT_ENA_RXFIFO_FULL_INT_ENA(1) 494 uart.Bus.SetINT_ENA_FRM_ERR_INT_ENA(1) 495 uart.Bus.SetINT_ENA_PARITY_ERR_INT_ENA(1) 496 uart.Bus.SetINT_ENA_GLITCH_DET_INT_ENA(1) 497 uart.Bus.SetINT_ENA_RXFIFO_OVF_INT_ENA(1) 498 } 499 500 func (uart *UART) writeByte(b byte) error { 501 for (uart.Bus.STATUS.Get()&esp.UART_STATUS_TXFIFO_CNT_Msk)>>esp.UART_STATUS_TXFIFO_CNT_Pos >= 128 { 502 // Read UART_TXFIFO_CNT from the status register, which indicates how 503 // many bytes there are in the transmit buffer. Wait until there are 504 // less than 128 bytes in this buffer (the default buffer size). 505 } 506 uart.Bus.FIFO.Set(uint32(b)) 507 return nil 508 } 509 510 func (uart *UART) flush() {} 511 512 type Serialer interface { 513 WriteByte(c byte) error 514 Write(data []byte) (n int, err error) 515 Configure(config UARTConfig) error 516 Buffered() int 517 ReadByte() (byte, error) 518 DTR() bool 519 RTS() bool 520 } 521 522 // USB Serial/JTAG Controller 523 // See esp32-c3_technical_reference_manual_en.pdf 524 // pg. 736 525 type USB_DEVICE struct { 526 Bus *esp.USB_DEVICE_Type 527 } 528 529 var ( 530 _USBCDC = &USB_DEVICE{ 531 Bus: esp.USB_DEVICE, 532 } 533 534 USBCDC Serialer = _USBCDC 535 ) 536 537 var ( 538 errUSBWrongSize = errors.New("USB: invalid write size") 539 errUSBCouldNotWriteAllData = errors.New("USB: could not write all data") 540 errUSBBufferEmpty = errors.New("USB: read buffer empty") 541 ) 542 543 func (usbdev *USB_DEVICE) Configure(config UARTConfig) error { 544 return nil 545 } 546 547 func (usbdev *USB_DEVICE) WriteByte(c byte) error { 548 if usbdev.Bus.GetEP1_CONF_SERIAL_IN_EP_DATA_FREE() == 0 { 549 return errUSBCouldNotWriteAllData 550 } 551 552 usbdev.Bus.SetEP1_RDWR_BYTE(uint32(c)) 553 usbdev.flush() 554 555 return nil 556 } 557 558 func (usbdev *USB_DEVICE) Write(data []byte) (n int, err error) { 559 if len(data) == 0 || len(data) > 64 { 560 return 0, errUSBWrongSize 561 } 562 563 for i, c := range data { 564 if usbdev.Bus.GetEP1_CONF_SERIAL_IN_EP_DATA_FREE() == 0 { 565 if i > 0 { 566 usbdev.flush() 567 } 568 569 return i, errUSBCouldNotWriteAllData 570 } 571 usbdev.Bus.SetEP1_RDWR_BYTE(uint32(c)) 572 } 573 574 usbdev.flush() 575 return len(data), nil 576 } 577 578 func (usbdev *USB_DEVICE) Buffered() int { 579 return int(usbdev.Bus.GetEP1_CONF_SERIAL_OUT_EP_DATA_AVAIL()) 580 } 581 582 func (usbdev *USB_DEVICE) ReadByte() (byte, error) { 583 if usbdev.Bus.GetEP1_CONF_SERIAL_OUT_EP_DATA_AVAIL() != 0 { 584 return byte(usbdev.Bus.GetEP1_RDWR_BYTE()), nil 585 } 586 587 return 0, nil 588 } 589 590 func (usbdev *USB_DEVICE) DTR() bool { 591 return false 592 } 593 594 func (usbdev *USB_DEVICE) RTS() bool { 595 return false 596 } 597 598 func (usbdev *USB_DEVICE) flush() { 599 usbdev.Bus.SetEP1_CONF_WR_DONE(1) 600 for usbdev.Bus.GetEP1_CONF_SERIAL_IN_EP_DATA_FREE() == 0 { 601 } 602 } 603 604 // GetRNG returns 32-bit random numbers using the ESP32-C3 true random number generator, 605 // Random numbers are generated based on the thermal noise in the system and the 606 // asynchronous clock mismatch. 607 // For maximum entropy also make sure that the SAR_ADC is enabled. 608 // See esp32-c3_technical_reference_manual_en.pdf p.524 609 func GetRNG() (ret uint32, err error) { 610 // ensure ADC clock is initialized 611 initADCClock() 612 613 // ensure fast RTC clock is enabled 614 if esp.RTC_CNTL.GetCLK_CONF_DIG_CLK8M_EN() == 0 { 615 esp.RTC_CNTL.SetCLK_CONF_DIG_CLK8M_EN(1) 616 } 617 618 return esp.APB_CTRL.GetRND_DATA(), nil 619 } 620 621 func initADCClock() { 622 if esp.APB_SARADC.GetCLKM_CONF_CLK_EN() == 1 { 623 return 624 } 625 626 // only support ADC_CTRL_CLK set to 1 627 esp.APB_SARADC.SetCLKM_CONF_CLK_SEL(1) 628 629 esp.APB_SARADC.SetCTRL_SARADC_SAR_CLK_GATED(1) 630 631 esp.APB_SARADC.SetCLKM_CONF_CLKM_DIV_NUM(15) 632 esp.APB_SARADC.SetCLKM_CONF_CLKM_DIV_B(1) 633 esp.APB_SARADC.SetCLKM_CONF_CLKM_DIV_A(0) 634 635 esp.APB_SARADC.SetCTRL_SARADC_SAR_CLK_DIV(1) 636 esp.APB_SARADC.SetCLKM_CONF_CLK_EN(1) 637 }