nrf24.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  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 nrf24_read_reg(const FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t* data, uint8_t size) {
  60. uint8_t tx[size + 1];
  61. uint8_t rx[size + 1];
  62. memset(rx, 0, size + 1);
  63. tx[0] = R_REGISTER | (REGISTER_MASK & reg);
  64. memset(&tx[1], 0, size);
  65. nrf24_spi_trx(handle, tx, rx, size + 1, nrf24_TIMEOUT);
  66. memcpy(data, &rx[1], size);
  67. return rx[0];
  68. }
  69. uint8_t nrf24_flush_rx(const FuriHalSpiBusHandle* handle) {
  70. uint8_t tx[] = {FLUSH_RX};
  71. uint8_t rx[] = {0};
  72. nrf24_spi_trx(handle, tx, rx, 1, nrf24_TIMEOUT);
  73. return rx[0];
  74. }
  75. uint8_t nrf24_get_rdp(const FuriHalSpiBusHandle* handle) {
  76. uint8_t rdp;
  77. nrf24_read_reg(handle, REG_RDP, &rdp, 1);
  78. return rdp;
  79. }
  80. uint8_t nrf24_status(const FuriHalSpiBusHandle* handle) {
  81. uint8_t status;
  82. uint8_t tx[] = {R_REGISTER | (REGISTER_MASK & REG_STATUS)};
  83. nrf24_spi_trx(handle, tx, &status, 1, nrf24_TIMEOUT);
  84. return status;
  85. }
  86. uint8_t nrf24_set_idle(const FuriHalSpiBusHandle* handle) {
  87. uint8_t status = 0;
  88. uint8_t cfg = 0;
  89. nrf24_read_reg(handle, REG_CONFIG, &cfg, 1);
  90. cfg &= 0xfc; // clear bottom two bits to power down the radio
  91. status = nrf24_write_reg(handle, REG_CONFIG, cfg);
  92. furi_hal_gpio_write(nrf24_CE_PIN, false);
  93. return status;
  94. }
  95. uint8_t nrf24_set_rx_mode(const FuriHalSpiBusHandle* handle, bool nodelay) {
  96. uint8_t status = 0;
  97. uint8_t cfg = 0;
  98. nrf24_read_reg(handle, REG_CONFIG, &cfg, 1);
  99. cfg |= 0x03; // PWR_UP, and PRIM_RX
  100. status = nrf24_write_reg(handle, REG_CONFIG, cfg);
  101. furi_hal_gpio_write(nrf24_CE_PIN, true);
  102. if(!nodelay) furi_delay_ms(2000);
  103. return status;
  104. }
  105. bool nrf24_check_connected(const FuriHalSpiBusHandle* handle) {
  106. uint8_t status = nrf24_status(handle);
  107. if(status != 0x00) {
  108. return true;
  109. } else {
  110. return false;
  111. }
  112. }