furi_hal_random.c 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. #include <furi_hal_random.h>
  2. #include <furi.h>
  3. #include <furi_hal.h>
  4. #include <stm32wbxx_ll_rng.h>
  5. #include <stm32wbxx_ll_hsem.h>
  6. #include <hw_conf.h>
  7. #define TAG "FuriHalRandom"
  8. static uint32_t furi_hal_random_read_rng() {
  9. while(LL_RNG_IsActiveFlag_CECS(RNG) && LL_RNG_IsActiveFlag_SECS(RNG) &&
  10. !LL_RNG_IsActiveFlag_DRDY(RNG)) {
  11. /* Error handling as described in RM0434, pg. 582-583 */
  12. if(LL_RNG_IsActiveFlag_CECS(RNG)) {
  13. /* Clock error occurred */
  14. LL_RNG_ClearFlag_CEIS(RNG);
  15. }
  16. if(LL_RNG_IsActiveFlag_SECS(RNG)) {
  17. /* Noise source error occurred */
  18. LL_RNG_ClearFlag_SEIS(RNG);
  19. for(uint32_t i = 0; i < 12; ++i) {
  20. const volatile uint32_t discard = LL_RNG_ReadRandData32(RNG);
  21. UNUSED(discard);
  22. }
  23. }
  24. }
  25. return LL_RNG_ReadRandData32(RNG);
  26. }
  27. uint32_t furi_hal_random_get() {
  28. while(LL_HSEM_1StepLock(HSEM, CFG_HW_RNG_SEMID))
  29. ;
  30. LL_RNG_Enable(RNG);
  31. const uint32_t random_val = furi_hal_random_read_rng();
  32. LL_RNG_Disable(RNG);
  33. LL_HSEM_ReleaseLock(HSEM, CFG_HW_RNG_SEMID, 0);
  34. return random_val;
  35. }
  36. void furi_hal_random_fill_buf(uint8_t* buf, uint32_t len) {
  37. while(LL_HSEM_1StepLock(HSEM, CFG_HW_RNG_SEMID))
  38. ;
  39. LL_RNG_Enable(RNG);
  40. for(uint32_t i = 0; i < len; i += 4) {
  41. const uint32_t random_val = furi_hal_random_read_rng();
  42. uint8_t len_cur = ((i + 4) < len) ? (4) : (len - i);
  43. memcpy(&buf[i], &random_val, len_cur);
  44. }
  45. LL_RNG_Disable(RNG);
  46. LL_HSEM_ReleaseLock(HSEM, CFG_HW_RNG_SEMID, 0);
  47. }
  48. void srand(unsigned seed) {
  49. UNUSED(seed);
  50. }
  51. int rand() {
  52. return (furi_hal_random_get() & RAND_MAX);
  53. }
  54. long random() {
  55. return (furi_hal_random_get() & RAND_MAX);
  56. }