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
*
* 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.
@ -140,16 +142,28 @@ namespace nfc {
private:
friend class NFCRemoteEndpoint;
friend class NFCRemoteInitiator;
friend class Type4RemoteInitiator;
nfc_transceiver_t* transceiver() const;
void polling_callback(nfc_err_t ret);
// NFC Stack scheduler
void scheduler_process(bool hw_interrupt);
// Callbacks from NFC stack
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;
events::EventQueue* _queue;
nfc_transceiver_t* _transceiver;
nfc_scheduler_t* _scheduler;
Timer _timer;
Timeout _timeout;
Delegate* _delegate;
bool _discovery_running;
};

View File

@ -24,15 +24,26 @@ using namespace mbed;
using namespace mbed::nfc;
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
_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)
@ -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)
{
NFCController* self = (NFCController*) pUserData;
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();
}