Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: nRF51_Vdd TextLCD BME280
NFCController.cpp
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2018 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #include "NFCController.h" 00018 #include "NFCControllerDriver.h" 00019 #include "Type4RemoteInitiator.h" 00020 00021 #include "stack/transceiver/transceiver.h" 00022 00023 using namespace mbed; 00024 using namespace mbed::nfc; 00025 00026 NFCController::NFCController(NFCControllerDriver *driver, events::EventQueue *queue, const Span<uint8_t> &ndef_buffer) : 00027 _driver(driver), _queue(queue), _transceiver(NULL), _scheduler(NULL), _delegate(NULL), _discovery_running(false), _ndef_buffer(ndef_buffer) 00028 { 00029 _driver->set_delegate(this); 00030 } 00031 00032 nfc_err_t NFCController::initialize() 00033 { 00034 MBED_ASSERT(_transceiver == NULL); // Initialize should only be called once 00035 _transceiver = _driver->initialize((nfc_scheduler_timer_t *)&_timer); // See implementation below 00036 00037 if (_transceiver == NULL) { 00038 // Initialization error 00039 return NFC_ERR_CONTROLLER; // Controller error 00040 } 00041 00042 // Recover scheduler 00043 _scheduler = transceiver_get_scheduler(_transceiver); 00044 00045 // Run scheduler for the first time 00046 _queue->call(this, &NFCController::scheduler_process, false); 00047 00048 return NFC_OK; 00049 } 00050 00051 void NFCController::set_delegate(Delegate *delegate) 00052 { 00053 _delegate = delegate; 00054 } 00055 00056 nfc_rf_protocols_bitmask_t NFCController::get_supported_rf_protocols() const 00057 { 00058 // nfc_rf_protocols_bitmask_t is mapped on NFC Forum types, nfc_tech_t is mapped on the underlying RF techs 00059 // We therefore need to convert these 00060 00061 nfc_rf_protocols_bitmask_t rf_protocols = {0}; 00062 nfc_tech_t initiator_tech; 00063 nfc_tech_t target_tech; 00064 _driver->get_supported_nfc_techs(&initiator_tech, &target_tech); 00065 00066 // Note: we only support ISO-DEP tag emulation in this release, 00067 // so mask out all other protocols 00068 00069 // rf_protocols.initiator_t1t = initiator_tech.nfc_type1; 00070 // rf_protocols.initiator_t2t = initiator_tech.nfc_type2; 00071 // rf_protocols.initiator_t3t = initiator_tech.nfc_type3; 00072 // rf_protocols.initiator_iso_dep = initiator_tech.nfc_iso_dep_a || initiator_tech.nfc_iso_dep_b; 00073 // rf_protocols.initiator_nfc_dep = initiator_tech.nfc_nfc_dep_a || initiator_tech.nfc_nfc_dep_f_212 || initiator_tech.nfc_nfc_dep_f_424; 00074 00075 // rf_protocols.target_t1t = target_tech.nfc_type1; 00076 // rf_protocols.target_t2t = target_tech.nfc_type2; 00077 // rf_protocols.target_t3t = target_tech.nfc_type3; 00078 rf_protocols.target_iso_dep = target_tech.nfc_iso_dep_a || target_tech.nfc_iso_dep_b; 00079 // rf_protocols.target_nfc_dep = target_tech.nfc_nfc_dep_a || target_tech.nfc_nfc_dep_f_212 || target_tech.nfc_nfc_dep_f_424; 00080 00081 return rf_protocols; 00082 } 00083 00084 nfc_err_t NFCController::configure_rf_protocols(nfc_rf_protocols_bitmask_t rf_protocols) 00085 { 00086 if (_discovery_running) { 00087 // Cannot configure RF protocols if discovery is running 00088 return NFC_ERR_BUSY; 00089 } 00090 00091 // Map to NFC techs 00092 nfc_tech_t initiator_tech = {0}; 00093 nfc_tech_t target_tech = {0}; 00094 00095 // Note: we only support ISO-DEP tag emulation in this release, 00096 // so mask out all other protocols 00097 00098 target_tech.nfc_iso_dep_a = target_tech.nfc_iso_dep_b = true; 00099 00100 // Configure polling options (no need to set bailing flags as we're only using target mode) 00101 polling_options_t options = {0}; 00102 options.listen_for = -1; // Listen forever 00103 00104 transceiver_set_protocols(_transceiver, initiator_tech, target_tech, options); 00105 00106 return NFC_OK; 00107 } 00108 00109 nfc_err_t NFCController::start_discovery() 00110 { 00111 if (_discovery_running) { 00112 // Cannot start discovery if it's already running 00113 return NFC_ERR_BUSY; 00114 } 00115 00116 transceiver_poll(_transceiver, &NFCController::s_polling_callback, this /* use this as callback argument */); 00117 00118 return NFC_OK; 00119 } 00120 00121 nfc_err_t NFCController::cancel_discovery() 00122 { 00123 if (!_discovery_running) { 00124 return NFC_OK; 00125 } 00126 00127 transceiver_abort(_transceiver); 00128 00129 return NFC_OK; 00130 } 00131 00132 nfc_transceiver_t *NFCController::transceiver() const 00133 { 00134 return _transceiver; 00135 } 00136 00137 void NFCController::polling_callback(nfc_err_t ret) 00138 { 00139 // Polling has completed 00140 _discovery_running = false; 00141 00142 NFC_DBG("Polling finished with result %u", ret); 00143 00144 if (ret == NFC_OK) { 00145 // Check if a remote initiator was detected and if so, instantiate it 00146 if (!transceiver_is_initiator_mode(_transceiver)) { 00147 nfc_tech_t active_tech = transceiver_get_active_techs(_transceiver); 00148 if ((active_tech.nfc_iso_dep_a || active_tech.nfc_iso_dep_b) && (_delegate != NULL)) { 00149 Type4RemoteInitiator *type4_remote_initiator_ptr = new (std::nothrow) Type4RemoteInitiator(this, _ndef_buffer); 00150 if (type4_remote_initiator_ptr != NULL) { 00151 SharedPtr<NFCRemoteInitiator> type4_remote_initiator(type4_remote_initiator_ptr); 00152 _delegate->on_nfc_initiator_discovered(type4_remote_initiator); 00153 } 00154 } 00155 } 00156 } 00157 00158 if (_delegate != NULL) { 00159 Delegate::nfc_discovery_terminated_reason_t reason; 00160 00161 // Map reason 00162 switch (ret) { 00163 case NFC_OK: 00164 reason = Delegate::nfc_discovery_terminated_completed; 00165 break; 00166 case NFC_ERR_ABORTED: 00167 reason = Delegate::nfc_discovery_terminated_canceled; 00168 break; 00169 default: 00170 // Any other error code means there was an error during the discovery process 00171 reason = Delegate::nfc_discovery_terminated_rf_error; 00172 break; 00173 } 00174 00175 _delegate->on_discovery_terminated(reason); 00176 } 00177 } 00178 00179 void NFCController::scheduler_process(bool hw_interrupt) 00180 { 00181 _timeout.detach(); // Cancel timeout - if it triggers, it's ok as we'll have an "early" iteration which will likely be a no-op 00182 00183 // Process stack events 00184 uint32_t timeout = nfc_scheduler_iteration(_scheduler, hw_interrupt ? EVENT_HW_INTERRUPT : EVENT_NONE); 00185 00186 _timeout.attach(callback(this, &NFCController::on_timeout), timeout); 00187 } 00188 00189 void NFCController::on_hw_interrupt() 00190 { 00191 // Run scheduler - this is called in interrupt context 00192 _timeout.detach(); // Cancel timeout - if it triggers anyways, it's ok 00193 _queue->call(this, &NFCController::scheduler_process, true); 00194 } 00195 00196 void NFCController::on_timeout() 00197 { 00198 // Run scheduler - this is called in interrupt context 00199 _queue->call(this, &NFCController::scheduler_process, false); 00200 } 00201 00202 void NFCController::s_polling_callback(nfc_transceiver_t *pTransceiver, nfc_err_t ret, void *pUserData) 00203 { 00204 NFCController *self = (NFCController *) pUserData; 00205 self->polling_callback(ret); 00206 } 00207 00208 // Implementation nfc_scheduler_timer_t 00209 void nfc_scheduler_timer_init(nfc_scheduler_timer_t *timer) 00210 { 00211 (void)timer; // This is a no-op 00212 } 00213 00214 void nfc_scheduler_timer_start(nfc_scheduler_timer_t *timer) 00215 { 00216 Timer *mbed_timer = (Timer *)timer; 00217 mbed_timer->start(); 00218 } 00219 00220 uint32_t nfc_scheduler_timer_get(nfc_scheduler_timer_t *timer) 00221 { 00222 Timer *mbed_timer = (Timer *)timer; 00223 return (uint32_t)mbed_timer->read_ms(); 00224 } 00225 00226 void nfc_scheduler_timer_stop(nfc_scheduler_timer_t *timer) 00227 { 00228 Timer *mbed_timer = (Timer *)timer; 00229 mbed_timer->stop(); 00230 } 00231 00232 void nfc_scheduler_timer_reset(nfc_scheduler_timer_t *timer) 00233 { 00234 Timer *mbed_timer = (Timer *)timer; 00235 mbed_timer->reset(); 00236 }
Generated on Tue Jul 12 2022 15:15:54 by
