machine/nrf52840: implement RNG peripheral operation
Этот коммит содержится в:
родитель
ea1e08f53f
коммит
4ba76a5df9
2 изменённых файлов: 62 добавлений и 2 удалений
|
@ -1,5 +1,5 @@
|
|||
//go:build stm32 || (sam && atsamd51) || (sam && atsame5x) || rp2040
|
||||
// +build stm32 sam,atsamd51 sam,atsame5x rp2040
|
||||
//go:build nrf52840 || stm32 || (sam && atsamd51) || (sam && atsame5x) || rp2040
|
||||
// +build nrf52840 stm32 sam,atsamd51 sam,atsame5x rp2040
|
||||
|
||||
package rand
|
||||
|
||||
|
|
60
src/machine/machine_nrf52840_rng.go
Обычный файл
60
src/machine/machine_nrf52840_rng.go
Обычный файл
|
@ -0,0 +1,60 @@
|
|||
//go:build nrf52840
|
||||
// +build nrf52840
|
||||
|
||||
package machine
|
||||
|
||||
import (
|
||||
"device/nrf"
|
||||
)
|
||||
|
||||
// Implementation based on Nordic Semiconductor's nRF52840 documentation version 1.7 found here:
|
||||
// https://infocenter.nordicsemi.com/pdf/nRF52840_PS_v1.7.pdf
|
||||
|
||||
// SetRNGBiasCorrection configures the RNG peripheral's bias correction mechanism. Note that when
|
||||
// bias correction is enabled, the peripheral is slower to produce random values.
|
||||
func SetRNGBiasCorrection(enabled bool) {
|
||||
var val uint32
|
||||
if enabled {
|
||||
val = nrf.RNG_CONFIG_DERCEN_Enabled
|
||||
}
|
||||
nrf.RNG.SetCONFIG_DERCEN(val)
|
||||
}
|
||||
|
||||
// RNGBiasCorrectionEnabled determines whether the RNG peripheral's bias correction mechanism is
|
||||
// enabled or not.
|
||||
func RNGBiasCorrectionEnabled() bool {
|
||||
return nrf.RNG.GetCONFIG_DERCEN() == nrf.RNG_CONFIG_DERCEN_Enabled
|
||||
}
|
||||
|
||||
// StartRNG starts the RNG peripheral core. This is automatically called by GetRNG, but can be
|
||||
// manually called for interacting with the RNG peripheral directly.
|
||||
func StartRNG() {
|
||||
nrf.RNG.SetTASKS_START(nrf.RNG_TASKS_START_TASKS_START_Trigger)
|
||||
}
|
||||
|
||||
// StopRNG stops the RNG peripheral core. This is not called automatically. It may make sense to
|
||||
// manually disable RNG peripheral for power conservation.
|
||||
func StopRNG() {
|
||||
nrf.RNG.SetTASKS_STOP(nrf.RNG_TASKS_STOP_TASKS_STOP_Trigger)
|
||||
}
|
||||
|
||||
// GetRNG returns 32 bits of non-deterministic random data based on internal thermal noise.
|
||||
// According to Nordic's documentation, the random output is suitable for cryptographic purposes.
|
||||
func GetRNG() (ret uint32, err error) {
|
||||
// There's no apparent way to check the status of the RNG peripheral's task, so simply start it
|
||||
// to avoid deadlocking while waiting for output.
|
||||
StartRNG()
|
||||
|
||||
// The RNG returns one byte at a time, so stack up four bytes into a single uint32 for return.
|
||||
for i := 0; i < 4; i++ {
|
||||
// Wait for data to be ready.
|
||||
for nrf.RNG.GetEVENTS_VALRDY() == nrf.RNG_EVENTS_VALRDY_EVENTS_VALRDY_NotGenerated {
|
||||
}
|
||||
// Append random byte to output.
|
||||
ret = (ret << 8) ^ nrf.RNG.GetVALUE()
|
||||
// Unset the EVENTS_VALRDY register to avoid reading the same random output twice.
|
||||
nrf.RNG.SetEVENTS_VALRDY(nrf.RNG_EVENTS_VALRDY_EVENTS_VALRDY_NotGenerated)
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
Загрузка…
Создание таблицы
Сослаться в новой задаче