api-hal-nfc.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. #include "api-hal-nfc.h"
  2. #include <st25r3916.h>
  3. static bool dev_is_found = false;
  4. const uint32_t clocks_in_ms = 64 * 1000;
  5. ReturnCode api_hal_nfc_init() {
  6. // Check if Nfc worker was started
  7. if(rfalNfcGetState() > RFAL_NFC_STATE_NOTINIT) {
  8. return ERR_NONE;
  9. }
  10. return rfalNfcInitialize();
  11. }
  12. bool api_hal_nfc_is_busy() {
  13. return rfalNfcGetState() > RFAL_NFC_STATE_IDLE;
  14. }
  15. void api_hal_nfc_field_on() {
  16. api_hal_nfc_exit_sleep();
  17. st25r3916TxRxOn();
  18. }
  19. void api_hal_nfc_field_off() {
  20. st25r3916TxRxOff();
  21. api_hal_nfc_start_sleep();
  22. }
  23. void api_hal_nfc_start_sleep() {
  24. rfalLowPowerModeStart();
  25. }
  26. void api_hal_nfc_exit_sleep() {
  27. rfalLowPowerModeStop();
  28. }
  29. static void api_hal_nfc_change_state_cb(rfalNfcState st) {
  30. FURI_LOG_D("HAL NFC", "NFC worker state: %d", st);
  31. if(st >= RFAL_NFC_STATE_POLL_SELECT) {
  32. dev_is_found = true;
  33. }
  34. }
  35. bool api_hal_nfc_detect(rfalNfcDevice **dev_list, uint8_t* dev_cnt, uint32_t cycles, bool deactivate) {
  36. furi_assert(dev_list);
  37. furi_assert(dev_cnt);
  38. rfalLowPowerModeStop();
  39. if(rfalNfcGetState() == RFAL_NFC_STATE_NOTINIT) {
  40. rfalNfcInitialize();
  41. }
  42. rfalNfcDiscoverParam params;
  43. params.compMode = RFAL_COMPLIANCE_MODE_EMV;
  44. params.techs2Find = RFAL_NFC_POLL_TECH_A | RFAL_NFC_POLL_TECH_B | RFAL_NFC_POLL_TECH_F |
  45. RFAL_NFC_POLL_TECH_V | RFAL_NFC_POLL_TECH_AP2P | RFAL_NFC_POLL_TECH_ST25TB;
  46. params.totalDuration = 1000;
  47. params.devLimit = 3;
  48. params.wakeupEnabled = false;
  49. params.wakeupConfigDefault = true;
  50. params.nfcfBR = RFAL_BR_212;
  51. params.ap2pBR = RFAL_BR_424;
  52. params.maxBR = RFAL_BR_KEEP;
  53. params.GBLen = RFAL_NFCDEP_GB_MAX_LEN;
  54. params.notifyCb = api_hal_nfc_change_state_cb;
  55. dev_is_found = false;
  56. rfalNfcDiscover(&params);
  57. while(--cycles) {
  58. rfalNfcWorker();
  59. FURI_LOG_D("HAL NFC", "Current state %d", rfalNfcGetState());
  60. if(dev_is_found) {
  61. rfalNfcGetDevicesFound(dev_list, dev_cnt);
  62. FURI_LOG_D("HAL NFC", "Found %d devices", dev_cnt);
  63. break;
  64. }
  65. osDelay(10);
  66. }
  67. if(deactivate) {
  68. rfalNfcDeactivate(false);
  69. rfalLowPowerModeStart();
  70. }
  71. if(!cycles) {
  72. FURI_LOG_D("HAL NFC", "Timeout");
  73. return false;
  74. }
  75. return true;
  76. }
  77. bool api_hal_nfc_listen(uint32_t timeout) {
  78. api_hal_nfc_exit_sleep();
  79. rfalLowPowerModeStop();
  80. rfalNfcState state = rfalNfcGetState();
  81. if(state == RFAL_NFC_STATE_NOTINIT) {
  82. rfalNfcInitialize();
  83. } else if(state >= RFAL_NFC_STATE_ACTIVATED) {
  84. rfalNfcDeactivate(false);
  85. }
  86. rfalNfcDiscoverParam params;
  87. params.compMode = RFAL_COMPLIANCE_MODE_EMV;
  88. params.techs2Find = RFAL_NFC_LISTEN_TECH_A;
  89. params.totalDuration = 1000;
  90. params.devLimit = 1;
  91. params.wakeupEnabled = false;
  92. params.wakeupConfigDefault = true;
  93. params.nfcfBR = RFAL_BR_212;
  94. params.ap2pBR = RFAL_BR_424;
  95. params.maxBR = RFAL_BR_KEEP;
  96. params.GBLen = RFAL_NFCDEP_GB_MAX_LEN;
  97. params.notifyCb = NULL;
  98. params.lmConfigPA.nfcidLen = RFAL_LM_NFCID_LEN_04;
  99. params.lmConfigPA.nfcid[0] = 0XCF;
  100. params.lmConfigPA.nfcid[1] = 0x72;
  101. params.lmConfigPA.nfcid[2] = 0xD4;
  102. params.lmConfigPA.nfcid[3] = 0x40;
  103. params.lmConfigPA.SENS_RES[0] = 0x04;
  104. params.lmConfigPA.SENS_RES[1] = 0x00;
  105. params.lmConfigPA.SEL_RES = 0x20;
  106. uint32_t start = DWT->CYCCNT;
  107. rfalNfcDiscover(&params);
  108. while(state != RFAL_NFC_STATE_ACTIVATED) {
  109. rfalNfcWorker();
  110. state = rfalNfcGetState();
  111. FURI_LOG_D("HAL NFC", "Current state %d", state);
  112. if(DWT->CYCCNT - start > timeout * clocks_in_ms) {
  113. rfalNfcDeactivate(true);
  114. return false;
  115. }
  116. if(state == RFAL_NFC_STATE_LISTEN_ACTIVATION) {
  117. continue;
  118. }
  119. taskYIELD();
  120. }
  121. return true;
  122. }
  123. ReturnCode api_hal_nfc_data_exchange(uint8_t* tx_buff, uint16_t tx_len, uint8_t** rx_buff, uint16_t** rx_len, bool deactivate) {
  124. furi_assert(rx_buff);
  125. furi_assert(rx_len);
  126. ReturnCode ret;
  127. rfalNfcState state = RFAL_NFC_STATE_ACTIVATED;
  128. ret = rfalNfcDataExchangeStart(tx_buff, tx_len, rx_buff, rx_len, 0);
  129. if(ret != ERR_NONE) {
  130. return ret;
  131. }
  132. uint32_t start = DWT->CYCCNT;
  133. while(state != RFAL_NFC_STATE_DATAEXCHANGE_DONE) {
  134. rfalNfcWorker();
  135. state = rfalNfcGetState();
  136. ret = rfalNfcDataExchangeGetStatus();
  137. FURI_LOG_D("HAL NFC", "Nfc st: %d Data st: %d", state, ret);
  138. if(ret > ERR_SLEEP_REQ) {
  139. return ret;
  140. }
  141. if(ret == ERR_BUSY) {
  142. if(DWT->CYCCNT - start > 1000 * clocks_in_ms) {
  143. return ERR_TIMEOUT;
  144. }
  145. continue;
  146. } else {
  147. start = DWT->CYCCNT;
  148. }
  149. taskYIELD();
  150. }
  151. if(deactivate) {
  152. rfalNfcDeactivate(false);
  153. rfalLowPowerModeStart();
  154. }
  155. return ERR_NONE;
  156. }
  157. void api_hal_nfc_deactivate() {
  158. rfalNfcDeactivate(false);
  159. rfalLowPowerModeStart();
  160. }