Add scheduler implementation to NFC Controller class

pull/7822/head
Donatien Garnier 2018-08-16 13:50:20 +01:00
parent 9056f29025
commit 8c4e4d855c
2 changed files with 75 additions and 5 deletions

View File

@ -93,8 +93,10 @@ namespace nfc {
* Initialize the NFC controller * Initialize the NFC controller
* *
* This method must be called before any other method call. * This method must be called before any other method call.
*
* @return NFC_OK, or an error.
*/ */
void initialize(); nfc_err_t initialize();
/** /**
* Set the delegate that will receive events generated by this controller. * Set the delegate that will receive events generated by this controller.
@ -140,16 +142,28 @@ namespace nfc {
private: private:
friend class NFCRemoteEndpoint; friend class NFCRemoteEndpoint;
friend class NFCRemoteInitiator; friend class NFCRemoteInitiator;
friend class Type4RemoteInitiator;
nfc_transceiver_t* transceiver() const; nfc_transceiver_t* transceiver() const;
void polling_callback(nfc_err_t ret); void polling_callback(nfc_err_t ret);
// NFC Stack scheduler
void scheduler_process(bool hw_interrupt);
// Callbacks from NFC stack // Callbacks from NFC stack
static void s_polling_callback(nfc_transceiver_t* pTransceiver, nfc_err_t ret, void* pUserData); static void s_polling_callback(nfc_transceiver_t* pTransceiver, nfc_err_t ret, void* pUserData);
// Implementation of NFCControllerDriver::Delegate
void on_hw_interrupt();
// Triggers when scheduler must be run again
void on_timeout();
NFCControllerDriver* _driver; NFCControllerDriver* _driver;
events::EventQueue* _queue; events::EventQueue* _queue;
nfc_transceiver_t* _transceiver; nfc_transceiver_t* _transceiver;
nfc_scheduler_t* _scheduler;
Timer _timer; Timer _timer;
Timeout _timeout;
Delegate* _delegate; Delegate* _delegate;
bool _discovery_running; bool _discovery_running;
}; };

View File

@ -24,15 +24,26 @@ using namespace mbed;
using namespace mbed::nfc; using namespace mbed::nfc;
NFCController::NFCController(NFCControllerDriver* driver, events::EventQueue* queue) : NFCController::NFCController(NFCControllerDriver* driver, events::EventQueue* queue) :
_driver(driver), _queue(queue), _transceiver(NULL), _delegate(NULL), _discovery_running(false) _driver(driver), _queue(queue), _transceiver(NULL), _scheduler(NULL), _delegate(NULL), _discovery_running(false)
{ {
_driver->set_delegate(this);
} }
void NFCController::initialize() nfc_err_t NFCController::initialize()
{ {
MBED_ASSERT(_transceiver == NULL); // Initialize should only be called once MBED_ASSERT(_transceiver == NULL); // Initialize should only be called once
_transceiver = _driver->initialize((nfc_scheduler_timer_t*)&_timer); _transceiver = _driver->initialize((nfc_scheduler_timer_t*)&_timer); // See implementation below
if( _transceiver == NULL ) {
// Initialization error
return NFC_ERR_CONTROLLER; // Controller error
}
// Recover scheduler
_scheduler = transceiver_get_scheduler(_transceiver);
// Run scheduler for the first time
_queue->call(this, NFCController::scheduler_process, false);
} }
void NFCController::set_delegate(Delegate* delegate) void NFCController::set_delegate(Delegate* delegate)
@ -153,8 +164,53 @@ void NFCController::polling_callback(nfc_err_t ret)
} }
} }
void NFCController::scheduler_process(bool hw_interrupt) {
_timer.detach(); // Cancel timeout - if it triggers, it's ok as we'll have an "early" iteration which will likely be a no-op
// Process stack events
uint32_t timeout = nfc_scheduler_iteration(_scheduler, hw_interrupt?EVENT_HW_INTERRUPT:EVENT_NONE);
_timer.attach(callback(this, &NFCController::on_timeout));
}
void NFCController::on_hw_interrupt() {
// Run scheduler - this is called in interrupt context
_timer.detach(); // Cancel timeout - if it triggers anyways, it's ok
_queue->call(this, NFCController::scheduler_process, true);
}
void NFCController::on_timeout() {
// Run scheduler - this is called in interrupt context
_queue->call(this, NFCController::scheduler_process, false);
}
static void NFCController::s_polling_callback(nfc_transceiver_t* pTransceiver, nfc_err_t ret, void* pUserData) static void NFCController::s_polling_callback(nfc_transceiver_t* pTransceiver, nfc_err_t ret, void* pUserData)
{ {
NFCController* self = (NFCController*) pUserData; NFCController* self = (NFCController*) pUserData;
self->polling_callback(ret); self->polling_callback(ret);
} }
// Implementation nfc_scheduler_timer_t
void nfc_scheduler_timer_init(nfc_scheduler_timer_t* timer) {
(void)timer; // This is a no-op
}
void nfc_scheduler_timer_start(nfc_scheduler_timer_t* timer) {
Timer* mbed_timer = (Timer*)timer;
mbed_timer->start();
}
uint32_t nfc_scheduler_timer_get(nfc_scheduler_timer_t* timer) {
Timer* mbed_timer = (Timer*)timer;
return (uint32_t)mbed_timer->read_ms();
}
void nfc_scheduler_timer_stop(nfc_scheduler_timer_t* timer) {
Timer* mbed_timer = (Timer*)timer;
mbed_timer->stop();
}
void nfc_scheduler_timer_reset(nfc_scheduler_timer_t* timer) {
Timer* mbed_timer = (Timer*)timer;
mbed_timer->reset();
}