mirror of https://github.com/ARMmbed/mbed-os.git
Writing implementation in NFC EEPROM
parent
28fad6b320
commit
5a9cab2408
|
@ -86,8 +86,9 @@ namespace nfc {
|
|||
*
|
||||
* @param[in] driver a pointer to a NFCControllerDriver instance
|
||||
* @param[in] queue a pointer to the events queue to use
|
||||
* @param[in] ndef_buffer_sz NDEF buffer size
|
||||
*/
|
||||
NFCController(NFCControllerDriver* driver, events::EventQueue* queue);
|
||||
NFCController(NFCControllerDriver* driver, events::EventQueue* queue, uint8_t* ndef_buffer, size_t ndef_buffer_sz);
|
||||
|
||||
/**
|
||||
* Initialize the NFC controller
|
||||
|
@ -166,6 +167,7 @@ namespace nfc {
|
|||
Timeout _timeout;
|
||||
Delegate* _delegate;
|
||||
bool _discovery_running;
|
||||
size_t _ndef_buffer_sz;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -48,10 +48,11 @@ namespace nfc {
|
|||
* Construct a NFCEEPROM instance.
|
||||
*
|
||||
* @param[in] driver a pointer to a NFCEEPROMDriver instance
|
||||
* @param[in] queue a pointer to the events queue to use
|
||||
* @param[in] ndef_buffer a bytes array used to store NDEF messages
|
||||
* @param[in] ndef_buffer_sz the array size in bytes
|
||||
*/
|
||||
NFCEEPROM(NFCEEPROMDriver* driver);
|
||||
|
||||
virtual ~NFCEEPROM();
|
||||
NFCEEPROM(NFCEEPROMDriver* driver, events::EventQueue* queue, uint8_t* ndef_buffer, size_t ndef_buffer_sz);
|
||||
|
||||
/**
|
||||
* The NFCEEPROM delegate. Users of the NFCEEPROM class need to implement this delegate's methods to receive events.
|
||||
|
@ -59,6 +60,15 @@ namespace nfc {
|
|||
struct Delegate : NFCTarget::Delegate {
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize the NFC EEPROM
|
||||
*
|
||||
* This method must be called before any other method call.
|
||||
*
|
||||
* @return NFC_OK, or an error.
|
||||
*/
|
||||
nfc_err_t initialize();
|
||||
|
||||
/**
|
||||
* Set the delegate that will receive events generated by this EEPROM.
|
||||
*
|
||||
|
@ -67,15 +77,47 @@ namespace nfc {
|
|||
void set_delegate(Delegate* delegate);
|
||||
|
||||
private:
|
||||
// Implementation of NFCTarget
|
||||
virtual void write_ndef_message();
|
||||
virtual void read_ndef_message();
|
||||
virtual void erase_ndef_message();
|
||||
|
||||
// Implementation of NFCEEPROMDriver::Delegate
|
||||
virtual void on_session_started(bool success);
|
||||
virtual void on_session_ended(bool success);
|
||||
virtual void on_bytes_read(size_t count);
|
||||
virtual void on_bytes_written(size_t count);
|
||||
virtual void on_size_set(bool success);
|
||||
virtual void on_size_gotten(bool success, size_t size);
|
||||
virtual void on_size_written(bool success);
|
||||
virtual void on_size_read(bool success, size_t size);
|
||||
virtual void on_bytes_erased(size_t count);
|
||||
virtual void on_event();
|
||||
|
||||
void handle_error(nfc_err_t ret);
|
||||
void continue_write();
|
||||
|
||||
enum class nfc_eeprom_operation_t {
|
||||
nfc_eeprom_idle,
|
||||
|
||||
nfc_eeprom_write_start_session,
|
||||
nfc_eeprom_write_write_bytes,
|
||||
nfc_eeprom_write_write_size,
|
||||
nfc_eeprom_write_end_session,
|
||||
|
||||
nfc_eeprom_write_start_session,
|
||||
nfc_eeprom_read_read_size,
|
||||
nfc_eeprom_read_read_bytes,
|
||||
nfc_eeprom_read_end_session
|
||||
};
|
||||
|
||||
NFCEEPROMDriver* _driver;
|
||||
events::EventQueue* _queue;
|
||||
bool _initialized;
|
||||
uint8_t* _ndef_buffer;
|
||||
size_t _ndef_buffer_sz;
|
||||
|
||||
nfc_eeprom_operation_t _current_op;
|
||||
buffer_t _ndef_buffer_reader;
|
||||
uint32_t _eeprom_address;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -40,8 +40,11 @@ namespace nfc {
|
|||
public:
|
||||
/**
|
||||
* Create a NFCTarget.
|
||||
*
|
||||
* @param[in] buffer a bytes array used to store NDEF messages
|
||||
* @param[in] buffer_size the array size in bytes
|
||||
*/
|
||||
NFCTarget();
|
||||
NFCTarget(uint8_t* buffer, size_t buffer_size);
|
||||
virtual ~NFCTarget();
|
||||
|
||||
struct Delegate {
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
using namespace mbed;
|
||||
using namespace mbed::nfc;
|
||||
|
||||
NFCController::NFCController(NFCControllerDriver* driver, events::EventQueue* queue) :
|
||||
_driver(driver), _queue(queue), _transceiver(NULL), _scheduler(NULL), _delegate(NULL), _discovery_running(false)
|
||||
NFCController::NFCController(NFCControllerDriver* driver, events::EventQueue* queue, size_t ndef_buffer_sz) :
|
||||
_driver(driver), _queue(queue), _transceiver(NULL), _scheduler(NULL), _delegate(NULL), _discovery_running(false), _ndef_buffer_sz(ndef_buffer_sz)
|
||||
{
|
||||
_driver->set_delegate(this);
|
||||
}
|
||||
|
@ -135,7 +135,7 @@ void NFCController::polling_callback(nfc_err_t ret)
|
|||
if( !transceiver_is_initiator_mode(_transceiver) ) {
|
||||
nfc_tech_t active_tech = transceiver_get_active_techs(_transceiver);
|
||||
if( active_tech.nfc_iso_dep_a || active_tech.nfc_iso_dep_b ) {
|
||||
SharedPtr<Type4RemoteInitiator> type4_remote_initiator( new Type4RemoteInitiator(_transceiver) );
|
||||
SharedPtr<Type4RemoteInitiator> type4_remote_initiator( new Type4RemoteInitiator(_transceiver, _ndef_buffer_sz) );
|
||||
if( _delegate != NULL ) {
|
||||
_delegate->on_nfc_initiator_discovered(type4_remote_initiator);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,241 @@
|
|||
/* 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 "NFCEEPROM.h"
|
||||
#include "ndef/ndef.h"
|
||||
|
||||
using namespace mbed;
|
||||
using namespace mbed::nfc;
|
||||
|
||||
NFCEEPROM(NFCEEPROMDriver* driver, events::EventQueue* queue, uint8_t* ndef_buffer, size_t ndef_buffer_sz) : NFCTarget( ndef_buffer, ndef_buffer_sz )
|
||||
_driver(driver), _queue(queue), _delegate(NULL), _initialized(false), _current_op(nfc_eeprom_idle), _eeprom_address(0)
|
||||
{
|
||||
_driver->set_delegate(this);
|
||||
}
|
||||
|
||||
nfc_err_t NFCEEPROM::initialize() {
|
||||
MBED_ASSERT(_initialized == false); // Initialize should only be called once
|
||||
|
||||
// Initialize driver
|
||||
_driver->reset();
|
||||
_initialized = true;
|
||||
}
|
||||
|
||||
void NFCEEPROM::set_delegate(NFCEEPROM::Delegate* delegate) {
|
||||
_delegate = delegate;
|
||||
}
|
||||
|
||||
void NFCEEPROM::write_ndef_message() {
|
||||
MBED_ASSERT(_initialized == true);
|
||||
if(_current_op != nfc_eeprom_idle) {
|
||||
if(_delegate != NULL) {
|
||||
_delegate->on_ndef_message_written(NFC_ERR_BUSY);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// First update NDEF message if required
|
||||
ndef_msg_encode(ndef_message());
|
||||
|
||||
_current_op = nfc_eeprom_write_start_session;
|
||||
|
||||
// Retrieve reader
|
||||
ac_buffer_dup(&_ndef_buffer_reader, ac_buffer_builder_buffer(ndef_msg_buffer_builder(ndef_message()) );
|
||||
|
||||
// Check that NDEF message is not too big
|
||||
if( ac_buffer_reader_readable(&_ndef_buffer_reader) > _driver->get_max_size() ) {
|
||||
handle_error(NFC_ERR_BUFFER_TOO_SMALL);
|
||||
return;
|
||||
}
|
||||
|
||||
// Reset EEPROM address
|
||||
_eeprom_address = 0;
|
||||
|
||||
// Go through the steps!
|
||||
_driver->start_session();
|
||||
|
||||
// 1 - Start session
|
||||
// 2 - Write bytes (can be repeated)
|
||||
// 3 - Set NDEF message size
|
||||
// 4 - End session
|
||||
}
|
||||
|
||||
void NFCEEPROM::read_ndef_message() {
|
||||
MBED_ASSERT(_initialized == true);
|
||||
if(_current_op != nfc_eeprom_idle) {
|
||||
if(_delegate != NULL) {
|
||||
_delegate->on_ndef_message_written(NFC_ERR_BUSY);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
_current_op = nfc_eeprom_read_start_session;
|
||||
|
||||
// Reset EEPROM address
|
||||
_eeprom_address = 0;
|
||||
|
||||
// Go through the steps!
|
||||
_driver->start_session();
|
||||
|
||||
// 1 - Start session
|
||||
// 2 - Get NDEF message size
|
||||
// 3 - Read bytes (can be repeated)
|
||||
// 4 - End session
|
||||
}
|
||||
|
||||
void NFCEEPROM::erase_ndef_message() {
|
||||
// We don't want to take any risks, so erase the whole address space
|
||||
// And set the message size to 0
|
||||
}
|
||||
|
||||
void NFCEEPROM::on_session_started(bool success) {
|
||||
switch(_current_op) {
|
||||
case nfc_eeprom_write_start_session:
|
||||
if(!success) {
|
||||
handle_error(NFC_ERR_CONTROLLER); // An EEPROM is not really a controller but close enough
|
||||
return;
|
||||
}
|
||||
_current_op = nfc_eeprom_write_write_bytes;
|
||||
continue_write();
|
||||
break;
|
||||
|
||||
case nfc_eeprom_read_start_session:
|
||||
if(!success) {
|
||||
handle_error(NFC_ERR_CONTROLLER);
|
||||
return;
|
||||
}
|
||||
_current_op = nfc_eeprom_read_read_size;
|
||||
_driver->read_size();
|
||||
break;
|
||||
|
||||
default:
|
||||
// Should not happen, state machine is broken or driver is doing something wrong
|
||||
handle_error(NFC_ERR_UNKNOWN);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void NFCEEPROM::on_session_ended(bool success) {
|
||||
switch(_current_op) {
|
||||
case nfc_eeprom_write_end_session:
|
||||
if(!success) {
|
||||
handle_error(NFC_ERR_CONTROLLER);
|
||||
return;
|
||||
}
|
||||
_current_op = nfc_eeprom_idle;
|
||||
if( _delegate != NULL ) {
|
||||
_driver->on_ndef_message_written(NFC_OK);
|
||||
}
|
||||
break;
|
||||
|
||||
case nfc_eeprom_read_end_session:
|
||||
if(!success) {
|
||||
handle_error(NFC_ERR_CONTROLLER);
|
||||
return;
|
||||
}
|
||||
_current_op = nfc_eeprom_idle;
|
||||
if( _delegate != NULL ) {
|
||||
_driver->on_ndef_message_read(NFC_OK);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// Should not happen, state machine is broken or driver is doing something wrong
|
||||
handle_error(NFC_ERR_UNKNOWN);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void NFCEEPROM::on_bytes_read(size_t count) {
|
||||
|
||||
}
|
||||
|
||||
void NFCEEPROM::on_bytes_written(size_t count) {
|
||||
switch(_current_op) {
|
||||
case nfc_eeprom_write_write_bytes:
|
||||
if(count == 0) {
|
||||
handle_error(NFC_ERR_CONTROLLER);
|
||||
return;
|
||||
}
|
||||
|
||||
// Discard bytes that were actually read and update address
|
||||
_eeprom_address += count;
|
||||
ac_buffer_read_n_skip(&_ndef_buffer_reader, count);
|
||||
|
||||
// Continue writing
|
||||
continue_write();
|
||||
break;
|
||||
default:
|
||||
// Should not happen, state machine is broken or driver is doing something wrong
|
||||
handle_error(NFC_ERR_UNKNOWN);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void NFCEEPROM::on_size_written(bool success) {
|
||||
switch(_current_op) {
|
||||
case nfc_eeprom_write_write_size:
|
||||
if(!success) {
|
||||
handle_error(NFC_ERR_CONTROLLER);
|
||||
return;
|
||||
}
|
||||
|
||||
// End session
|
||||
_current_op = nfc_eeprom_write_end_session;
|
||||
_driver->end_session();
|
||||
break;
|
||||
default:
|
||||
// Should not happen, state machine is broken or driver is doing something wrong
|
||||
handle_error(NFC_ERR_UNKNOWN);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void NFCEEPROM::on_size_read(bool success, size_t size) {
|
||||
|
||||
}
|
||||
|
||||
void NFCEEPROM::on_bytes_erased(size_t count) {
|
||||
|
||||
}
|
||||
|
||||
void NFCEEPROM::on_event() {
|
||||
|
||||
}
|
||||
|
||||
void NFCEEPROM::continue_write() {
|
||||
if( ac_buffer_reader_readable(&_ndef_buffer_reader) > 0 ) {
|
||||
// Continue writing
|
||||
_driver->write_bytes(_eeprom_address, ac_buffer_reader_current_buffer_pointer(&_ndef_buffer_reader), ac_buffer_reader_current_buffer_length(&_ndef_buffer_reader));
|
||||
}
|
||||
else {
|
||||
// Now update size
|
||||
_current_op = nfc_eeprom_write_set_size;
|
||||
_driver->write_size(_eeprom_address);
|
||||
}
|
||||
}
|
||||
|
||||
void NFCEEPROM::handle_error(nfc_err_t ret) {
|
||||
// Save & reset current op
|
||||
nfc_eeprom_operation_t last_op = _current_op;
|
||||
_current_op = nfc_eeprom_idle;
|
||||
|
||||
if(_delegate != NULL) {
|
||||
if(last_op <= nfc_eeprom_write_end_session) {
|
||||
_delegate->on_ndef_message_written(NFC_ERR_BUSY);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue