mirror of https://github.com/ARMmbed/mbed-os.git
Erase & Read implementations in NFCEEPROM
parent
5a9cab2408
commit
9fcca783b9
|
@ -94,6 +94,8 @@ namespace nfc {
|
||||||
|
|
||||||
void handle_error(nfc_err_t ret);
|
void handle_error(nfc_err_t ret);
|
||||||
void continue_write();
|
void continue_write();
|
||||||
|
void continue_read();
|
||||||
|
void continue_erase();
|
||||||
|
|
||||||
enum class nfc_eeprom_operation_t {
|
enum class nfc_eeprom_operation_t {
|
||||||
nfc_eeprom_idle,
|
nfc_eeprom_idle,
|
||||||
|
@ -106,7 +108,12 @@ namespace nfc {
|
||||||
nfc_eeprom_write_start_session,
|
nfc_eeprom_write_start_session,
|
||||||
nfc_eeprom_read_read_size,
|
nfc_eeprom_read_read_size,
|
||||||
nfc_eeprom_read_read_bytes,
|
nfc_eeprom_read_read_bytes,
|
||||||
nfc_eeprom_read_end_session
|
nfc_eeprom_read_end_session,
|
||||||
|
|
||||||
|
nfc_eeprom_erase_start_session,
|
||||||
|
nfc_eeprom_erase_erase_bytes,
|
||||||
|
nfc_eeprom_erase_write_size,
|
||||||
|
nfc_eeprom_erase_end_session
|
||||||
};
|
};
|
||||||
|
|
||||||
NFCEEPROMDriver* _driver;
|
NFCEEPROMDriver* _driver;
|
||||||
|
@ -117,7 +124,9 @@ namespace nfc {
|
||||||
|
|
||||||
nfc_eeprom_operation_t _current_op;
|
nfc_eeprom_operation_t _current_op;
|
||||||
buffer_t _ndef_buffer_reader;
|
buffer_t _ndef_buffer_reader;
|
||||||
|
size_t _ndef_buffer_read_sz;
|
||||||
uint32_t _eeprom_address;
|
uint32_t _eeprom_address;
|
||||||
|
nfc_err_t _operation_result;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -21,7 +21,7 @@ using namespace mbed;
|
||||||
using namespace mbed::nfc;
|
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 )
|
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(driver), _queue(queue), _initialized(false), _current_op(nfc_eeprom_idle), _eeprom_address(0), _operation_result(NFC_ERR_UNKNOWN)
|
||||||
{
|
{
|
||||||
_driver->set_delegate(this);
|
_driver->set_delegate(this);
|
||||||
}
|
}
|
||||||
|
@ -99,6 +99,27 @@ void NFCEEPROM::read_ndef_message() {
|
||||||
void NFCEEPROM::erase_ndef_message() {
|
void NFCEEPROM::erase_ndef_message() {
|
||||||
// We don't want to take any risks, so erase the whole address space
|
// We don't want to take any risks, so erase the whole address space
|
||||||
// And set the message size to 0
|
// And set the message size to 0
|
||||||
|
|
||||||
|
MBED_ASSERT(_initialized == true);
|
||||||
|
if(_current_op != nfc_eeprom_idle) {
|
||||||
|
if(_delegate != NULL) {
|
||||||
|
_delegate->on_ndef_message_erased(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 - Erase bytes (can be repeated)
|
||||||
|
// 3 - Set NDEF message size to 0
|
||||||
|
// 4 - End session
|
||||||
}
|
}
|
||||||
|
|
||||||
void NFCEEPROM::on_session_started(bool success) {
|
void NFCEEPROM::on_session_started(bool success) {
|
||||||
|
@ -121,6 +142,15 @@ void NFCEEPROM::on_session_started(bool success) {
|
||||||
_driver->read_size();
|
_driver->read_size();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case nfc_eeprom_erase_start_session:
|
||||||
|
if(!success) {
|
||||||
|
handle_error(NFC_ERR_CONTROLLER);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_current_op = nfc_eeprom_erase_bytes;
|
||||||
|
continue_erase();
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// Should not happen, state machine is broken or driver is doing something wrong
|
// Should not happen, state machine is broken or driver is doing something wrong
|
||||||
handle_error(NFC_ERR_UNKNOWN);
|
handle_error(NFC_ERR_UNKNOWN);
|
||||||
|
@ -137,7 +167,7 @@ void NFCEEPROM::on_session_ended(bool success) {
|
||||||
}
|
}
|
||||||
_current_op = nfc_eeprom_idle;
|
_current_op = nfc_eeprom_idle;
|
||||||
if( _delegate != NULL ) {
|
if( _delegate != NULL ) {
|
||||||
_driver->on_ndef_message_written(NFC_OK);
|
_driver->on_ndef_message_written(_operation_result);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -147,11 +177,26 @@ void NFCEEPROM::on_session_ended(bool success) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_current_op = nfc_eeprom_idle;
|
_current_op = nfc_eeprom_idle;
|
||||||
|
|
||||||
|
// Try to parse the NDEF message
|
||||||
|
ndef_msg_decode(ndef_message());
|
||||||
|
|
||||||
if( _delegate != NULL ) {
|
if( _delegate != NULL ) {
|
||||||
_driver->on_ndef_message_read(NFC_OK);
|
_driver->on_ndef_message_read(_operation_result);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case nfc_eeprom_erase_end_session:
|
||||||
|
if(!success) {
|
||||||
|
handle_error(NFC_ERR_CONTROLLER);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_current_op = nfc_eeprom_idle;
|
||||||
|
if( _delegate != NULL ) {
|
||||||
|
_driver->on_ndef_message_erased(_operation_result);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// Should not happen, state machine is broken or driver is doing something wrong
|
// Should not happen, state machine is broken or driver is doing something wrong
|
||||||
handle_error(NFC_ERR_UNKNOWN);
|
handle_error(NFC_ERR_UNKNOWN);
|
||||||
|
@ -160,7 +205,26 @@ void NFCEEPROM::on_session_ended(bool success) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void NFCEEPROM::on_bytes_read(size_t count) {
|
void NFCEEPROM::on_bytes_read(size_t count) {
|
||||||
|
switch(_current_op) {
|
||||||
|
case nfc_eeprom_read_read_bytes:
|
||||||
|
if(count == 0) {
|
||||||
|
handle_error(NFC_ERR_CONTROLLER);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Discard bytes that were actually read and update address
|
||||||
|
_eeprom_address += count;
|
||||||
|
ac_buffer_builder_t* buffer_builder = ndef_msg_buffer_builder(ndef_message());
|
||||||
|
ac_buffer_builder_write_n_skip(buffer_builder, count);
|
||||||
|
|
||||||
|
// Continue reading
|
||||||
|
continue_read();
|
||||||
|
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_written(size_t count) {
|
void NFCEEPROM::on_bytes_written(size_t count) {
|
||||||
|
@ -171,7 +235,7 @@ void NFCEEPROM::on_bytes_written(size_t count) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Discard bytes that were actually read and update address
|
// Skip bytes that were actually written and update address
|
||||||
_eeprom_address += count;
|
_eeprom_address += count;
|
||||||
ac_buffer_read_n_skip(&_ndef_buffer_reader, count);
|
ac_buffer_read_n_skip(&_ndef_buffer_reader, count);
|
||||||
|
|
||||||
|
@ -195,6 +259,18 @@ void NFCEEPROM::on_size_written(bool success) {
|
||||||
|
|
||||||
// End session
|
// End session
|
||||||
_current_op = nfc_eeprom_write_end_session;
|
_current_op = nfc_eeprom_write_end_session;
|
||||||
|
_operation_result = NFC_OK;
|
||||||
|
_driver->end_session();
|
||||||
|
break;
|
||||||
|
case nfc_eeprom_erase_write_size:
|
||||||
|
if(!success) {
|
||||||
|
handle_error(NFC_ERR_CONTROLLER);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// End session
|
||||||
|
_current_op = nfc_eeprom_erase_end_session;
|
||||||
|
_operation_result = NFC_OK;
|
||||||
_driver->end_session();
|
_driver->end_session();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -205,15 +281,66 @@ void NFCEEPROM::on_size_written(bool success) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void NFCEEPROM::on_size_read(bool success, size_t size) {
|
void NFCEEPROM::on_size_read(bool success, size_t size) {
|
||||||
|
switch(_current_op) {
|
||||||
|
case nfc_eeprom_read_read_size:
|
||||||
|
if(!success) {
|
||||||
|
handle_error(NFC_ERR_CONTROLLER);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset NDEF message buffer builder
|
||||||
|
ac_buffer_builder_t* buffer_builder = ndef_msg_buffer_builder(ndef_message());
|
||||||
|
ac_buffer_builder_reset( buffer_builder );
|
||||||
|
|
||||||
|
// Check that we have a big enough buffer to read the message
|
||||||
|
if( size > ac_buffer_builder_writable(buffer_builder) )
|
||||||
|
{
|
||||||
|
// Not enough space, close session
|
||||||
|
_current_op = nfc_eeprom_read_end_session;
|
||||||
|
_operation_result = NFC_ERR_BUFFER_TOO_SMALL;
|
||||||
|
_driver->end_session();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save size and reset address
|
||||||
|
_eeprom_address = 0;
|
||||||
|
_ndef_buffer_read_sz = size;
|
||||||
|
|
||||||
|
// Start reading bytes
|
||||||
|
_current_op = nfc_eeprom_read_read_bytes;
|
||||||
|
continue_read();
|
||||||
|
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_erased(size_t count) {
|
void NFCEEPROM::on_bytes_erased(size_t count) {
|
||||||
|
switch(_current_op) {
|
||||||
|
case nfc_eeprom_erase_erase_bytes:
|
||||||
|
if(count == 0) {
|
||||||
|
handle_error(NFC_ERR_CONTROLLER);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update address
|
||||||
|
_eeprom_address += count;
|
||||||
|
|
||||||
|
// Continue erasing
|
||||||
|
continue_erase();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Should not happen, state machine is broken or driver is doing something wrong
|
||||||
|
handle_error(NFC_ERR_UNKNOWN);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NFCEEPROM::on_event() {
|
void NFCEEPROM::on_event() {
|
||||||
|
// Just schedule a task on event queue
|
||||||
|
_queue->call(_driver, NFCEEPROMDriver::process_events);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NFCEEPROM::continue_write() {
|
void NFCEEPROM::continue_write() {
|
||||||
|
@ -223,11 +350,36 @@ void NFCEEPROM::continue_write() {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Now update size
|
// Now update size
|
||||||
_current_op = nfc_eeprom_write_set_size;
|
_current_op = nfc_eeprom_write_write_size;
|
||||||
_driver->write_size(_eeprom_address);
|
_driver->write_size(_eeprom_address);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NFCEEPROM::continue_erase() {
|
||||||
|
if( _eeprom_address < _driver->get_max_size() ) {
|
||||||
|
// Continue erasing
|
||||||
|
_driver->erase_bytes(_eeprom_address, _driver->get_max_size() - _eeprom_address);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Now update size
|
||||||
|
_current_op = nfc_eeprom_erase_write_size;
|
||||||
|
_driver->write_size(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NFCEEPROM::continue_read() {
|
||||||
|
if( _eeprom_address < _ndef_buffer_read_sz ) {
|
||||||
|
// Continue reading
|
||||||
|
ac_buffer_builder_t* buffer_builder = ndef_msg_buffer_builder(ndef_message());
|
||||||
|
_driver->read_bytes(_eeprom_address, ac_buffer_builder_write_position(buffer_builder), _ndef_buffer_read_sz - _eeprom_address);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Done, close session
|
||||||
|
_operation_result = NFC_OK;
|
||||||
|
_driver->end_session();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void NFCEEPROM::handle_error(nfc_err_t ret) {
|
void NFCEEPROM::handle_error(nfc_err_t ret) {
|
||||||
// Save & reset current op
|
// Save & reset current op
|
||||||
nfc_eeprom_operation_t last_op = _current_op;
|
nfc_eeprom_operation_t last_op = _current_op;
|
||||||
|
@ -235,7 +387,13 @@ void NFCEEPROM::handle_error(nfc_err_t ret) {
|
||||||
|
|
||||||
if(_delegate != NULL) {
|
if(_delegate != NULL) {
|
||||||
if(last_op <= nfc_eeprom_write_end_session) {
|
if(last_op <= nfc_eeprom_write_end_session) {
|
||||||
_delegate->on_ndef_message_written(NFC_ERR_BUSY);
|
_delegate->on_ndef_message_written(ret);
|
||||||
|
}
|
||||||
|
else if(last_op <= nfc_eeprom_read_end_session) {
|
||||||
|
_delegate->on_ndef_message_read(ret);
|
||||||
|
}
|
||||||
|
else if(last_op <= nfc_eeprom_erase_end_session) {
|
||||||
|
_delegate->on_ndef_message_erased(ret);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue