nrf24.c 3.2 KB

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