nrf24.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. #include "nrf24.h"
  2. #include <furi.h>
  3. #include <furi_hal.h>
  4. #include <furi_hal_resources.h>
  5. #include <assert.h>
  6. #include <string.h>
  7. void nrf24_init() {
  8. // this is needed if multiple SPI devices are connected to the same bus but with different CS pins
  9. #ifdef MOMENTUM_SETTINGS_PATH
  10. if(momentum_settings.spi_nrf24_handle == SpiDefault) {
  11. furi_hal_gpio_init_simple(&gpio_ext_pc3, GpioModeOutputPushPull);
  12. furi_hal_gpio_write(&gpio_ext_pc3, true);
  13. } else if(momentum_settings.spi_nrf24_handle == SpiExtra) {
  14. furi_hal_gpio_init_simple(&gpio_ext_pa4, GpioModeOutputPushPull);
  15. furi_hal_gpio_write(&gpio_ext_pa4, true);
  16. }
  17. #else
  18. furi_hal_gpio_init_simple(&gpio_ext_pc3, GpioModeOutputPushPull);
  19. furi_hal_gpio_write(&gpio_ext_pc3, true);
  20. #endif
  21. furi_hal_spi_bus_handle_init(nrf24_HANDLE);
  22. furi_hal_spi_acquire(nrf24_HANDLE);
  23. furi_hal_gpio_init(nrf24_CE_PIN, GpioModeOutputPushPull, GpioPullUp, GpioSpeedVeryHigh);
  24. furi_hal_gpio_write(nrf24_CE_PIN, false);
  25. }
  26. void nrf24_deinit() {
  27. furi_hal_spi_release(nrf24_HANDLE);
  28. furi_hal_spi_bus_handle_deinit(nrf24_HANDLE);
  29. furi_hal_gpio_write(nrf24_CE_PIN, false);
  30. furi_hal_gpio_init(nrf24_CE_PIN, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
  31. #ifdef MOMENTUM_SETTINGS_PATH
  32. // resetting the CS pins to floating
  33. if(momentum_settings.spi_nrf24_handle == SpiDefault) {
  34. furi_hal_gpio_init_simple(&gpio_ext_pc3, GpioModeAnalog);
  35. } else if(momentum_settings.spi_nrf24_handle == SpiExtra) {
  36. furi_hal_gpio_init_simple(&gpio_ext_pa4, GpioModeAnalog);
  37. }
  38. #else
  39. furi_hal_gpio_init_simple(&gpio_ext_pc3, GpioModeAnalog);
  40. #endif
  41. }
  42. void nrf24_spi_trx(
  43. const FuriHalSpiBusHandle* handle,
  44. uint8_t* tx,
  45. uint8_t* rx,
  46. uint8_t size,
  47. uint32_t timeout) {
  48. UNUSED(timeout);
  49. furi_hal_gpio_write(handle->cs, false);
  50. furi_hal_spi_bus_trx(handle, tx, rx, size, nrf24_TIMEOUT);
  51. furi_hal_gpio_write(handle->cs, true);
  52. }
  53. uint8_t nrf24_write_reg(const FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t data) {
  54. uint8_t tx[2] = {W_REGISTER | (REGISTER_MASK & reg), data};
  55. uint8_t rx[2] = {0};
  56. nrf24_spi_trx(handle, tx, rx, 2, nrf24_TIMEOUT);
  57. return rx[0];
  58. }
  59. uint8_t
  60. nrf24_read_reg(const FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t* data, uint8_t size) {
  61. uint8_t tx[size + 1];
  62. uint8_t rx[size + 1];
  63. memset(rx, 0, size + 1);
  64. tx[0] = R_REGISTER | (REGISTER_MASK & reg);
  65. memset(&tx[1], 0, size);
  66. nrf24_spi_trx(handle, tx, rx, size + 1, nrf24_TIMEOUT);
  67. memcpy(data, &rx[1], size);
  68. return rx[0];
  69. }
  70. uint8_t nrf24_flush_rx(const FuriHalSpiBusHandle* handle) {
  71. uint8_t tx[] = {FLUSH_RX};
  72. uint8_t rx[] = {0};
  73. nrf24_spi_trx(handle, tx, rx, 1, nrf24_TIMEOUT);
  74. return rx[0];
  75. }
  76. uint8_t nrf24_get_rdp(const FuriHalSpiBusHandle* handle) {
  77. uint8_t rdp;
  78. nrf24_read_reg(handle, REG_RDP, &rdp, 1);
  79. return rdp;
  80. }
  81. uint8_t nrf24_status(const FuriHalSpiBusHandle* handle) {
  82. uint8_t status;
  83. uint8_t tx[] = {R_REGISTER | (REGISTER_MASK & REG_STATUS)};
  84. nrf24_spi_trx(handle, tx, &status, 1, nrf24_TIMEOUT);
  85. return status;
  86. }
  87. uint8_t nrf24_set_idle(const FuriHalSpiBusHandle* handle) {
  88. uint8_t status = 0;
  89. uint8_t cfg = 0;
  90. nrf24_read_reg(handle, REG_CONFIG, &cfg, 1);
  91. cfg &= 0xfc; // clear bottom two bits to power down the radio
  92. status = nrf24_write_reg(handle, REG_CONFIG, cfg);
  93. furi_hal_gpio_write(nrf24_CE_PIN, false);
  94. return status;
  95. }
  96. uint8_t nrf24_set_rx_mode(const FuriHalSpiBusHandle* handle, bool nodelay) {
  97. uint8_t status = 0;
  98. uint8_t cfg = 0;
  99. nrf24_read_reg(handle, REG_CONFIG, &cfg, 1);
  100. cfg |= 0x03; // PWR_UP, and PRIM_RX
  101. status = nrf24_write_reg(handle, REG_CONFIG, cfg);
  102. furi_hal_gpio_write(nrf24_CE_PIN, true);
  103. if(!nodelay) furi_delay_ms(2000);
  104. return status;
  105. }
  106. bool nrf24_check_connected(const FuriHalSpiBusHandle* handle) {
  107. uint8_t status = nrf24_status(handle);
  108. if(status != 0x00) {
  109. return true;
  110. } else {
  111. return false;
  112. }
  113. }