nrf24.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  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. if(XTREME_SETTINGS()->spi_nrf24_handle == SpiDefault) {
  10. furi_hal_gpio_init_simple(&gpio_ext_pc3, GpioModeOutputPushPull);
  11. furi_hal_gpio_write(&gpio_ext_pc3, true);
  12. } else if(XTREME_SETTINGS()->spi_nrf24_handle == SpiExtra) {
  13. furi_hal_gpio_init_simple(&gpio_ext_pa4, GpioModeOutputPushPull);
  14. furi_hal_gpio_write(&gpio_ext_pa4, true);
  15. }
  16. furi_hal_spi_bus_handle_init(nrf24_HANDLE);
  17. furi_hal_spi_acquire(nrf24_HANDLE);
  18. furi_hal_gpio_init(nrf24_CE_PIN, GpioModeOutputPushPull, GpioPullUp, GpioSpeedVeryHigh);
  19. furi_hal_gpio_write(nrf24_CE_PIN, false);
  20. }
  21. void nrf24_deinit() {
  22. furi_hal_spi_release(nrf24_HANDLE);
  23. furi_hal_spi_bus_handle_deinit(nrf24_HANDLE);
  24. furi_hal_gpio_write(nrf24_CE_PIN, false);
  25. furi_hal_gpio_init(nrf24_CE_PIN, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
  26. // resetting the CS pins to floating
  27. if(XTREME_SETTINGS()->spi_nrf24_handle == SpiDefault) {
  28. furi_hal_gpio_init_simple(&gpio_ext_pc3, GpioModeAnalog);
  29. } else if(XTREME_SETTINGS()->spi_nrf24_handle == SpiExtra) {
  30. furi_hal_gpio_init_simple(&gpio_ext_pa4, GpioModeAnalog);
  31. }
  32. }
  33. void nrf24_spi_trx(
  34. FuriHalSpiBusHandle* handle,
  35. uint8_t* tx,
  36. uint8_t* rx,
  37. uint8_t size,
  38. uint32_t timeout) {
  39. UNUSED(timeout);
  40. furi_hal_gpio_write(handle->cs, false);
  41. furi_hal_spi_bus_trx(handle, tx, rx, size, nrf24_TIMEOUT);
  42. furi_hal_gpio_write(handle->cs, true);
  43. }
  44. uint8_t nrf24_write_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t data) {
  45. uint8_t tx[2] = {W_REGISTER | (REGISTER_MASK & reg), data};
  46. uint8_t rx[2] = {0};
  47. nrf24_spi_trx(handle, tx, rx, 2, nrf24_TIMEOUT);
  48. return rx[0];
  49. }
  50. uint8_t nrf24_read_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t* data, uint8_t size) {
  51. uint8_t tx[size + 1];
  52. uint8_t rx[size + 1];
  53. memset(rx, 0, size + 1);
  54. tx[0] = R_REGISTER | (REGISTER_MASK & reg);
  55. memset(&tx[1], 0, size);
  56. nrf24_spi_trx(handle, tx, rx, size + 1, nrf24_TIMEOUT);
  57. memcpy(data, &rx[1], size);
  58. return rx[0];
  59. }
  60. uint8_t nrf24_flush_rx(FuriHalSpiBusHandle* handle) {
  61. uint8_t tx[] = {FLUSH_RX};
  62. uint8_t rx[] = {0};
  63. nrf24_spi_trx(handle, tx, rx, 1, nrf24_TIMEOUT);
  64. return rx[0];
  65. }
  66. uint8_t nrf24_get_rdp(FuriHalSpiBusHandle* handle) {
  67. uint8_t rdp;
  68. nrf24_read_reg(handle, REG_RDP, &rdp, 1);
  69. return rdp;
  70. }
  71. uint8_t nrf24_status(FuriHalSpiBusHandle* handle) {
  72. uint8_t status;
  73. uint8_t tx[] = {R_REGISTER | (REGISTER_MASK & REG_STATUS)};
  74. nrf24_spi_trx(handle, tx, &status, 1, nrf24_TIMEOUT);
  75. return status;
  76. }
  77. uint8_t nrf24_set_idle(FuriHalSpiBusHandle* handle) {
  78. uint8_t status = 0;
  79. uint8_t cfg = 0;
  80. nrf24_read_reg(handle, REG_CONFIG, &cfg, 1);
  81. cfg &= 0xfc; // clear bottom two bits to power down the radio
  82. status = nrf24_write_reg(handle, REG_CONFIG, cfg);
  83. furi_hal_gpio_write(nrf24_CE_PIN, false);
  84. return status;
  85. }
  86. uint8_t nrf24_set_rx_mode(FuriHalSpiBusHandle* handle, bool nodelay) {
  87. uint8_t status = 0;
  88. uint8_t cfg = 0;
  89. nrf24_read_reg(handle, REG_CONFIG, &cfg, 1);
  90. cfg |= 0x03; // PWR_UP, and PRIM_RX
  91. status = nrf24_write_reg(handle, REG_CONFIG, cfg);
  92. furi_hal_gpio_write(nrf24_CE_PIN, true);
  93. if(!nodelay) furi_delay_ms(2000);
  94. return status;
  95. }
  96. bool nrf24_check_connected(FuriHalSpiBusHandle* handle) {
  97. uint8_t status = nrf24_status(handle);
  98. if(status != 0x00) {
  99. return true;
  100. } else {
  101. return false;
  102. }
  103. }