Kenji Arai / TYBLE16_mbedlized_os5_several_examples_1st

Dependencies:   nRF51_Vdd TextLCD BME280

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers NFCEEPROM.cpp Source File

NFCEEPROM.cpp

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2018 ARM Limited
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #include "NFCEEPROM.h"
00018 #include "ndef/ndef.h"
00019 
00020 using namespace mbed;
00021 using namespace mbed::nfc;
00022 
00023 NFCEEPROM::NFCEEPROM(NFCEEPROMDriver *driver, events::EventQueue *queue, const Span<uint8_t>  &ndef_buffer) : NFCTarget(ndef_buffer),
00024     _delegate(NULL), _driver(driver), _initialized(false), _current_op(nfc_eeprom_idle), _ndef_buffer_read_sz(0), _eeprom_address(0), _operation_result(NFC_ERR_UNKNOWN)
00025 {
00026     _driver->set_delegate(this);
00027     _driver->set_event_queue(queue);
00028 }
00029 
00030 nfc_err_t NFCEEPROM::initialize()
00031 {
00032     MBED_ASSERT(_initialized == false); // Initialize should only be called once
00033 
00034     // Initialize driver
00035     _driver->reset();
00036     _initialized = true;
00037     return NFC_OK;
00038 }
00039 
00040 void NFCEEPROM::set_delegate(NFCEEPROM::Delegate *delegate)
00041 {
00042     _delegate = delegate;
00043 }
00044 
00045 void NFCEEPROM::write_ndef_message()
00046 {
00047     MBED_ASSERT(_initialized == true);
00048     if (_current_op != nfc_eeprom_idle) {
00049         if (_delegate != NULL) {
00050             _delegate->on_ndef_message_written(NFC_ERR_BUSY);
00051         }
00052         return;
00053     }
00054 
00055     // First update NDEF message if required
00056     ndef_msg_encode(ndef_message());
00057 
00058     _current_op = nfc_eeprom_write_start_session;
00059 
00060     // Retrieve reader
00061     ac_buffer_dup(&_ndef_buffer_reader, ac_buffer_builder_buffer(ndef_msg_buffer_builder(ndef_message())));
00062 
00063     // Check that NDEF message is not too big
00064     if (ac_buffer_reader_readable(&_ndef_buffer_reader) > _driver->read_max_size()) {
00065         handle_error(NFC_ERR_BUFFER_TOO_SMALL);
00066         return;
00067     }
00068 
00069     // Reset EEPROM address
00070     _eeprom_address = 0;
00071 
00072     // Go through the steps!
00073     _driver->start_session();
00074 
00075     // 1 - Start session
00076     // 2 - Write bytes (can be repeated)
00077     // 3 - Set NDEF message size
00078     // 4 - End session
00079 }
00080 
00081 void NFCEEPROM::read_ndef_message()
00082 {
00083     MBED_ASSERT(_initialized == true);
00084     if (_current_op != nfc_eeprom_idle) {
00085         if (_delegate != NULL) {
00086             _delegate->on_ndef_message_written(NFC_ERR_BUSY);
00087         }
00088         return;
00089     }
00090 
00091     _current_op = nfc_eeprom_read_start_session;
00092 
00093     // Reset EEPROM address
00094     _eeprom_address = 0;
00095 
00096     // Go through the steps!
00097     _driver->start_session();
00098 
00099     // 1 - Start session
00100     // 2 - Get NDEF message size
00101     // 3 - Read bytes (can be repeated)
00102     // 4 - End session
00103 }
00104 
00105 void NFCEEPROM::erase_ndef_message()
00106 {
00107     // We don't want to take any risks, so erase the whole address space
00108     // And set the message size to 0
00109 
00110     MBED_ASSERT(_initialized == true);
00111     if (_current_op != nfc_eeprom_idle) {
00112         if (_delegate != NULL) {
00113             _delegate->on_ndef_message_erased(NFC_ERR_BUSY);
00114         }
00115         return;
00116     }
00117 
00118     _current_op = nfc_eeprom_read_start_session;
00119 
00120     // Reset EEPROM address
00121     _eeprom_address = 0;
00122 
00123     // Go through the steps!
00124     _driver->start_session();
00125 
00126     // 1 - Start session
00127     // 2 - Set addressable size to the max
00128     // 3 - Erase bytes (can be repeated)
00129     // 4 - Set addressable size to 0
00130     // 5 - End session
00131 }
00132 
00133 void NFCEEPROM::on_session_started(bool success)
00134 {
00135     switch (_current_op) {
00136         case nfc_eeprom_write_start_session:
00137             if (!success) {
00138                 handle_error(NFC_ERR_CONTROLLER); // An EEPROM is not really a controller but close enough
00139                 return;
00140             }
00141             _current_op = nfc_eeprom_write_write_size;
00142             _driver->write_size(ac_buffer_reader_readable(&_ndef_buffer_reader));
00143             break;
00144 
00145         case nfc_eeprom_read_start_session:
00146             if (!success) {
00147                 handle_error(NFC_ERR_CONTROLLER);
00148                 return;
00149             }
00150             _current_op = nfc_eeprom_read_read_size;
00151             _driver->read_size();
00152             break;
00153 
00154         case nfc_eeprom_erase_start_session:
00155             if (!success) {
00156                 handle_error(NFC_ERR_CONTROLLER);
00157                 return;
00158             }
00159 
00160             _current_op = nfc_eeprom_erase_write_max_size;
00161             _driver->write_size(_driver->read_max_size());
00162             break;
00163 
00164         default:
00165             // Should not happen, state machine is broken or driver is doing something wrong
00166             handle_error(NFC_ERR_UNKNOWN);
00167             return;
00168     }
00169 }
00170 
00171 void NFCEEPROM::on_session_ended(bool success)
00172 {
00173     switch (_current_op) {
00174         case nfc_eeprom_write_end_session:
00175             if (!success) {
00176                 handle_error(NFC_ERR_CONTROLLER);
00177                 return;
00178             }
00179             _current_op = nfc_eeprom_idle;
00180             if (_delegate != NULL) {
00181                 _delegate->on_ndef_message_written(_operation_result);
00182             }
00183             break;
00184 
00185         case nfc_eeprom_read_end_session:
00186             if (!success) {
00187                 handle_error(NFC_ERR_CONTROLLER);
00188                 return;
00189             }
00190             _current_op = nfc_eeprom_idle;
00191 
00192             // Try to parse the NDEF message
00193             ndef_msg_decode(ndef_message());
00194 
00195             if (_delegate != NULL) {
00196                 _delegate->on_ndef_message_read(_operation_result);
00197             }
00198             break;
00199 
00200         case nfc_eeprom_erase_end_session:
00201             if (!success) {
00202                 handle_error(NFC_ERR_CONTROLLER);
00203                 return;
00204             }
00205             _current_op = nfc_eeprom_idle;
00206             if (_delegate != NULL) {
00207                 _delegate->on_ndef_message_erased(_operation_result);
00208             }
00209             break;
00210 
00211         default:
00212             // Should not happen, state machine is broken or driver is doing something wrong
00213             handle_error(NFC_ERR_UNKNOWN);
00214             return;
00215     }
00216 }
00217 
00218 void NFCEEPROM::on_bytes_read(size_t count)
00219 {
00220     switch (_current_op) {
00221         case nfc_eeprom_read_read_bytes: {
00222             if (count == 0) {
00223                 handle_error(NFC_ERR_CONTROLLER);
00224                 return;
00225             }
00226 
00227             // Discard bytes that were actually read and update address
00228             _eeprom_address += count;
00229             ac_buffer_builder_t *buffer_builder = ndef_msg_buffer_builder(ndef_message());
00230             ac_buffer_builder_write_n_skip(buffer_builder, count);
00231 
00232             // Continue reading
00233             continue_read();
00234             break;
00235         }
00236         default:
00237             // Should not happen, state machine is broken or driver is doing something wrong
00238             handle_error(NFC_ERR_UNKNOWN);
00239             return;
00240     }
00241 }
00242 
00243 void NFCEEPROM::on_bytes_written(size_t count)
00244 {
00245     switch (_current_op) {
00246         case nfc_eeprom_write_write_bytes:
00247             if (count == 0) {
00248                 handle_error(NFC_ERR_CONTROLLER);
00249                 return;
00250             }
00251 
00252             // Skip bytes that were actually written and update address
00253             _eeprom_address += count;
00254             ac_buffer_read_n_skip(&_ndef_buffer_reader, count);
00255 
00256             // Continue writing
00257             continue_write();
00258             break;
00259         default:
00260             // Should not happen, state machine is broken or driver is doing something wrong
00261             handle_error(NFC_ERR_UNKNOWN);
00262             return;
00263     }
00264 }
00265 
00266 void NFCEEPROM::on_size_written(bool success)
00267 {
00268     switch (_current_op) {
00269         case nfc_eeprom_write_write_size:
00270             if (!success) {
00271                 handle_error(NFC_ERR_CONTROLLER);
00272                 return;
00273             }
00274 
00275             _current_op = nfc_eeprom_write_write_bytes;
00276             continue_write();
00277             break;
00278         case nfc_eeprom_erase_write_max_size:
00279             if (!success) {
00280                 handle_error(NFC_ERR_CONTROLLER);
00281                 return;
00282             }
00283 
00284             // Start erasing bytes
00285             _current_op = nfc_eeprom_erase_erase_bytes;
00286             continue_erase();
00287             break;
00288         case nfc_eeprom_erase_write_0_size:
00289             if (!success) {
00290                 handle_error(NFC_ERR_CONTROLLER);
00291                 return;
00292             }
00293 
00294             // End session
00295             _current_op = nfc_eeprom_erase_end_session;
00296             _operation_result = NFC_OK;
00297             _driver->end_session();
00298             break;
00299         default:
00300             // Should not happen, state machine is broken or driver is doing something wrong
00301             handle_error(NFC_ERR_UNKNOWN);
00302             return;
00303     }
00304 }
00305 
00306 void NFCEEPROM::on_size_read(bool success, size_t size)
00307 {
00308     switch (_current_op) {
00309         case nfc_eeprom_read_read_size: {
00310             if (!success) {
00311                 handle_error(NFC_ERR_CONTROLLER);
00312                 return;
00313             }
00314 
00315             // Reset NDEF message buffer builder
00316             ac_buffer_builder_t *buffer_builder = ndef_msg_buffer_builder(ndef_message());
00317             ac_buffer_builder_reset(buffer_builder);
00318 
00319             // Check that we have a big enough buffer to read the message
00320             if (size > ac_buffer_builder_writable(buffer_builder)) {
00321                 // Not enough space, close session
00322                 _current_op = nfc_eeprom_read_end_session;
00323                 _operation_result = NFC_ERR_BUFFER_TOO_SMALL;
00324                 _driver->end_session();
00325                 return;
00326             }
00327 
00328             // Save size and reset address
00329             _eeprom_address = 0;
00330             _ndef_buffer_read_sz = size;
00331 
00332             // Start reading bytes
00333             _current_op = nfc_eeprom_read_read_bytes;
00334             continue_read();
00335             break;
00336         }
00337         default:
00338             // Should not happen, state machine is broken or driver is doing something wrong
00339             handle_error(NFC_ERR_UNKNOWN);
00340             return;
00341     }
00342 }
00343 
00344 void NFCEEPROM::on_bytes_erased(size_t count)
00345 {
00346     switch (_current_op) {
00347         case nfc_eeprom_erase_erase_bytes:
00348             if (count == 0) {
00349                 handle_error(NFC_ERR_CONTROLLER);
00350                 return;
00351             }
00352 
00353             // Update address
00354             _eeprom_address += count;
00355 
00356             // Continue erasing
00357             continue_erase();
00358             break;
00359         default:
00360             // Should not happen, state machine is broken or driver is doing something wrong
00361             handle_error(NFC_ERR_UNKNOWN);
00362             return;
00363     }
00364 }
00365 
00366 void NFCEEPROM::continue_write()
00367 {
00368     if (ac_buffer_reader_readable(&_ndef_buffer_reader) > 0) {
00369         // Continue writing
00370         _driver->write_bytes(_eeprom_address, ac_buffer_reader_current_buffer_pointer(&_ndef_buffer_reader), ac_buffer_reader_current_buffer_length(&_ndef_buffer_reader));
00371     } else {
00372         // we are done
00373         _current_op = nfc_eeprom_write_end_session;
00374         _operation_result = NFC_OK;
00375         _driver->end_session();
00376     }
00377 }
00378 
00379 void NFCEEPROM::continue_erase()
00380 {
00381     if (_eeprom_address < _driver->read_max_size()) {
00382         // Continue erasing
00383         _driver->erase_bytes(_eeprom_address, _driver->read_max_size() - _eeprom_address);
00384     } else {
00385         // Now update size
00386         _current_op = nfc_eeprom_erase_write_0_size;
00387         _driver->write_size(0);
00388     }
00389 }
00390 
00391 void NFCEEPROM::continue_read()
00392 {
00393     if (_eeprom_address < _ndef_buffer_read_sz) {
00394         // Continue reading
00395         ac_buffer_builder_t *buffer_builder = ndef_msg_buffer_builder(ndef_message());
00396         _driver->read_bytes(_eeprom_address, ac_buffer_builder_write_position(buffer_builder), _ndef_buffer_read_sz - _eeprom_address);
00397     } else {
00398         // Done, close session
00399         _current_op = nfc_eeprom_read_end_session;
00400         _operation_result = NFC_OK;
00401         _driver->end_session();
00402     }
00403 }
00404 
00405 void NFCEEPROM::handle_error(nfc_err_t ret)
00406 {
00407     // Save & reset current op
00408     nfc_eeprom_operation_t last_op = _current_op;
00409     _current_op = nfc_eeprom_idle;
00410 
00411     if (_delegate != NULL) {
00412         if (last_op <= nfc_eeprom_write_end_session) {
00413             _delegate->on_ndef_message_written(ret);
00414         } else if (last_op <= nfc_eeprom_read_end_session) {
00415             _delegate->on_ndef_message_read(ret);
00416         } else if (last_op <= nfc_eeprom_erase_end_session) {
00417             _delegate->on_ndef_message_erased(ret);
00418         }
00419     }
00420 }
00421 
00422 NFCNDEFCapable::Delegate *NFCEEPROM::ndef_capable_delegate()
00423 {
00424     return _delegate;
00425 }