diff --git a/features/nfc/controllers/PN512Driver.h b/features/nfc/controllers/PN512Driver.h index 229194ea0f..374a7a49f0 100644 --- a/features/nfc/controllers/PN512Driver.h +++ b/features/nfc/controllers/PN512Driver.h @@ -30,13 +30,14 @@ namespace nfc { public: PN512Driver(PN512TransportDriver* transport_driver); - virtual void initialize(nfc_scheduler_timer_t* pTimer) = 0; - virtual nfc_transceiver_t* get_transceiver() const; + virtual nfc_transceiver_t* initialize(nfc_scheduler_timer_t* scheduler_timer); + virtual void get_supported_nfc_techs(nfc_tech_t* initiator, nfc_tech_t* target) const; private: // PN512TransportDriver::Delegate implementation void on_hw_interrupt(); + PN512TransportDriver* _transport_driver; pn512_t _pn512; }; diff --git a/features/nfc/nfc/NFCControllerDriver.h b/features/nfc/nfc/NFCControllerDriver.h index 27e64b1dda..a1aecec522 100644 --- a/features/nfc/nfc/NFCControllerDriver.h +++ b/features/nfc/nfc/NFCControllerDriver.h @@ -36,14 +36,29 @@ namespace nfc { * The abstraction for a NFC controller driver. * Implementers need to derive from this class and implement its methods. */ - struct NFCControllerDriver { + class NFCControllerDriver { + /** + * Instantiate a NFCControllerDriver + */ + NFCControllerDriver(); + + /** + * The NFCControllerDriver delegate + */ + struct Delegate { + /** + * Called when the controller asserts the interrupt line + */ + void on_hw_interrupt(); + }; + /** * Initialize the driver and retrieve the interface to the controller. * - * @param[in] pTimer The MicroNFC timer instance for the scheduler to use + * @param[in] scheduler_timer a timer to initialize the controller's scheduler instance with * @return an initialized MicroNFC nfc_transceiver_t instance */ - virtual nfc_transceiver_t* initialize(nfc_scheduler_timer_t* timer) = 0; + virtual nfc_transceiver_t* initialize(nfc_scheduler_timer_t* scheduler_timer) = 0; /** * Retrieve list of technologies supported by the controller @@ -51,6 +66,22 @@ namespace nfc { * @param[out] target bitmask of technologies supported when the controller is in target mode */ virtual void get_supported_nfc_techs(nfc_tech_t* initiator, nfc_tech_t* target) const = 0; + + /** + * Set this instance's delegate + * + * @param[in] delegate the delegate instance to use + */ + void set_delegate(Delegate* delegate); + protected: + + /** + * An implementation must call this function (can be called from interrupt context) + * when the controller asserts its interrupt line + */ + void hw_interrupt(); + private: + Delegate* _delegate; }; /** diff --git a/features/nfc/source/controllers/PN512Driver.cpp b/features/nfc/source/controllers/PN512Driver.cpp index e77f976f6c..e1ae254cd5 100644 --- a/features/nfc/source/controllers/PN512Driver.cpp +++ b/features/nfc/source/controllers/PN512Driver.cpp @@ -15,3 +15,46 @@ */ #include "PN512Driver.h" + +PN512Driver::PN512Driver(PN512TransportDriver* transport_driver) : NFCControllerDriver(), _transport_driver(transport_driver) { + _transport_driver->set_delegate(this); +} + +nfc_transceiver_t* PN512Driver::initialize(nfc_scheduler_timer_t* scheduler_timer) { + // Initialize transport + _transport_driver->initialize(); + + nfc_err_t ret = pn512_init(&pn512, _transport_driver->get_transport(), scheduler_timer); + if( ret != NFC_OK ) + { + NFC_ERR("PN512 init error (%d)", ret); + return NULL; + } + NFC_DBG("PN512 Initialized"); + + return pn512_get_transceiver(&pn512); +} + +void PN512Driver::get_supported_nfc_techs(nfc_tech_t* initiator, nfc_tech_t* target) const { + initiator->nfc_type1 = 0; + initiator->nfc_type2 = 1; + initiator->nfc_type3 = 1; + initiator->nfc_iso_dep_a = 1; + initiator->nfc_iso_dep_b = 0; + initiator->nfc_nfc_dep_a = 1; + initiator->nfc_nfc_dep_f_212 = 1; + initiator->nfc_nfc_dep_f_424 = 1; + + target->nfc_type1 = 0; + target->nfc_type2 = 0; + target->nfc_type3 = 0; + target->nfc_iso_dep_a = 1; + target->nfc_iso_dep_b = 0; + target->nfc_nfc_dep_a = 1; + target->nfc_nfc_dep_f_212 = 1; + target->nfc_nfc_dep_f_424 = 1; +} + +void PN512Driver::on_hw_interrupt() { + hw_interrupt(); // Propagate interrupt signal +} diff --git a/features/nfc/source/controllers/PN512TransportDriver.cpp b/features/nfc/source/controllers/PN512TransportDriver.cpp index 8dcf011c47..7cda922d98 100644 --- a/features/nfc/source/controllers/PN512TransportDriver.cpp +++ b/features/nfc/source/controllers/PN512TransportDriver.cpp @@ -19,7 +19,7 @@ using namespace mbed; using namespace mbed::nfc; -PN512TransportDriver::PN512TransportDriver() : _delegate() { +PN512TransportDriver::PN512TransportDriver() : _delegate(NULL) { } @@ -31,4 +31,4 @@ void PN512TransportDriver::hw_interrupt() { if(_delegate != NULL) { _delegate->on_hw_interrupt(); } -} \ No newline at end of file +} diff --git a/features/nfc/source/nfc/NFCControllerDriver.cpp b/features/nfc/source/nfc/NFCControllerDriver.cpp new file mode 100644 index 0000000000..3a7381149e --- /dev/null +++ b/features/nfc/source/nfc/NFCControllerDriver.cpp @@ -0,0 +1,34 @@ +/* mbed Microcontroller Library + * Copyright (c) 2018 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "NFCControllerDriver.h" + +using namespace mbed; +using namespace mbed::nfc; + +NFCControllerDriver::NFCControllerDriver() : _delegate(NULL) { + +} + +void NFCControllerDriver::set_delegate(Delegate* delegate) { + _delegate = delegate; +} + +void NFCControllerDriver::hw_interrupt() { + if(_delegate != NULL) { + _delegate->on_hw_interrupt(); + } +}