Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
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), _event_queue(queue), _initialized(false), _current_op(nfc_eeprom_idle), _ndef_buffer_read_sz(0), _eeprom_address(0), 00025 _operation_result(NFC_ERR_UNKNOWN), _ndef_buffer_reader{nullptr, 0, nullptr} 00026 { 00027 _driver->set_delegate(this); 00028 _driver->set_event_queue(queue); 00029 } 00030 00031 nfc_err_t NFCEEPROM::initialize() 00032 { 00033 MBED_ASSERT(_initialized == false); // Initialize should only be called once 00034 00035 // Initialize driver 00036 _driver->reset(); 00037 _initialized = true; 00038 return NFC_OK; 00039 } 00040 00041 void NFCEEPROM::set_delegate(NFCEEPROM::Delegate *delegate) 00042 { 00043 _delegate = delegate; 00044 } 00045 00046 void NFCEEPROM::write_ndef_message() 00047 { 00048 MBED_ASSERT(_initialized == true); 00049 if (_current_op != nfc_eeprom_idle) { 00050 if (_delegate != NULL) { 00051 _delegate->on_ndef_message_written(NFC_ERR_BUSY); 00052 } 00053 return; 00054 } 00055 00056 // First update NDEF message if required 00057 ndef_msg_encode(ndef_message()); 00058 00059 _current_op = nfc_eeprom_write_start_session; 00060 00061 // Retrieve reader 00062 ac_buffer_dup(&_ndef_buffer_reader, ac_buffer_builder_buffer(ndef_msg_buffer_builder(ndef_message()))); 00063 00064 // Check that NDEF message is not too big 00065 if (ac_buffer_reader_readable(&_ndef_buffer_reader) > _driver->read_max_size()) { 00066 handle_error(NFC_ERR_BUFFER_TOO_SMALL); 00067 return; 00068 } 00069 00070 // Reset EEPROM address 00071 _eeprom_address = 0; 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 _current_op = nfc_eeprom_read_start_session; 00091 00092 // Reset EEPROM address 00093 _eeprom_address = 0; 00094 00095 // Go through the steps! 00096 _driver->start_session(); 00097 00098 // 1 - Start session 00099 // 2 - Get NDEF message size 00100 // 3 - Read bytes (can be repeated) 00101 // 4 - End session 00102 } 00103 00104 void NFCEEPROM::erase_ndef_message() 00105 { 00106 // We don't want to take any risks, so erase the whole address space 00107 // And set the message size to 0 00108 00109 MBED_ASSERT(_initialized == true); 00110 if (_current_op != nfc_eeprom_idle) { 00111 if (_delegate != NULL) { 00112 _delegate->on_ndef_message_erased(NFC_ERR_BUSY); 00113 } 00114 return; 00115 } 00116 _current_op = nfc_eeprom_erase_start_session; 00117 00118 // Reset EEPROM address 00119 _eeprom_address = 0; 00120 00121 // Go through the steps! 00122 _driver->start_session(); 00123 00124 // 1 - Start session 00125 // 2 - Set addressable size to the max 00126 // 3 - Erase bytes (can be repeated) 00127 // 4 - Set addressable size to 0 00128 // 5 - End session 00129 } 00130 00131 void NFCEEPROM::on_session_started(bool success) 00132 { 00133 switch (_current_op) { 00134 case nfc_eeprom_write_start_session: 00135 if (!success) { 00136 handle_error(NFC_ERR_CONTROLLER); // An EEPROM is not really a controller but close enough 00137 return; 00138 } 00139 _current_op = nfc_eeprom_write_write_size; 00140 _driver->write_size(ac_buffer_reader_readable(&_ndef_buffer_reader)); 00141 break; 00142 00143 case nfc_eeprom_read_start_session: 00144 if (!success) { 00145 handle_error(NFC_ERR_CONTROLLER); 00146 return; 00147 } 00148 _current_op = nfc_eeprom_read_read_size; 00149 _driver->read_size(); 00150 break; 00151 00152 case nfc_eeprom_erase_start_session: 00153 if (!success) { 00154 handle_error(NFC_ERR_CONTROLLER); 00155 return; 00156 } 00157 00158 _current_op = nfc_eeprom_erase_write_max_size; 00159 _driver->write_size(_driver->read_max_size()); 00160 break; 00161 00162 default: 00163 // Should not happen, state machine is broken or driver is doing something wrong 00164 handle_error(NFC_ERR_UNKNOWN); 00165 return; 00166 } 00167 } 00168 00169 void NFCEEPROM::on_session_ended(bool success) 00170 { 00171 switch (_current_op) { 00172 case nfc_eeprom_write_end_session: 00173 if (!success) { 00174 handle_error(NFC_ERR_CONTROLLER); 00175 return; 00176 } 00177 _current_op = nfc_eeprom_idle; 00178 if (_delegate != NULL) { 00179 _delegate->on_ndef_message_written(_operation_result); 00180 } 00181 break; 00182 00183 case nfc_eeprom_read_end_session: 00184 if (!success) { 00185 handle_error(NFC_ERR_CONTROLLER); 00186 return; 00187 } 00188 _current_op = nfc_eeprom_idle; 00189 00190 // Try to parse the NDEF message 00191 ndef_msg_decode(ndef_message()); 00192 00193 if (_delegate != NULL) { 00194 _delegate->on_ndef_message_read(_operation_result); 00195 } 00196 break; 00197 00198 case nfc_eeprom_erase_end_session: 00199 if (!success) { 00200 handle_error(NFC_ERR_CONTROLLER); 00201 return; 00202 } 00203 _current_op = nfc_eeprom_idle; 00204 if (_delegate != NULL) { 00205 _delegate->on_ndef_message_erased(_operation_result); 00206 } 00207 break; 00208 00209 default: 00210 // Should not happen, state machine is broken or driver is doing something wrong 00211 handle_error(NFC_ERR_UNKNOWN); 00212 return; 00213 } 00214 } 00215 00216 void NFCEEPROM::on_bytes_read(size_t count) 00217 { 00218 switch (_current_op) { 00219 case nfc_eeprom_read_read_bytes: { 00220 if (count == 0) { 00221 handle_error(NFC_ERR_CONTROLLER); 00222 return; 00223 } 00224 00225 // Discard bytes that were actually read and update address 00226 _eeprom_address += count; 00227 ac_buffer_builder_t *buffer_builder = ndef_msg_buffer_builder(ndef_message()); 00228 ac_buffer_builder_write_n_skip(buffer_builder, count); 00229 00230 // Continue reading 00231 _event_queue->call(this, &NFCEEPROM::continue_read); 00232 break; 00233 } 00234 default: 00235 // Should not happen, state machine is broken or driver is doing something wrong 00236 handle_error(NFC_ERR_UNKNOWN); 00237 return; 00238 } 00239 } 00240 00241 void NFCEEPROM::on_bytes_written(size_t count) 00242 { 00243 switch (_current_op) { 00244 case nfc_eeprom_write_write_bytes: 00245 if (count == 0) { 00246 handle_error(NFC_ERR_CONTROLLER); 00247 return; 00248 } 00249 00250 // Skip bytes that were actually written and update address 00251 _eeprom_address += count; 00252 ac_buffer_read_n_skip(&_ndef_buffer_reader, count); 00253 00254 // Continue writing 00255 _event_queue->call(this, &NFCEEPROM::continue_write); 00256 break; 00257 default: 00258 // Should not happen, state machine is broken or driver is doing something wrong 00259 handle_error(NFC_ERR_UNKNOWN); 00260 return; 00261 } 00262 } 00263 00264 void NFCEEPROM::on_size_written(bool success) 00265 { 00266 switch (_current_op) { 00267 case nfc_eeprom_write_write_size: 00268 if (!success) { 00269 handle_error(NFC_ERR_CONTROLLER); 00270 return; 00271 } 00272 00273 _current_op = nfc_eeprom_write_write_bytes; 00274 continue_write(); 00275 break; 00276 case nfc_eeprom_erase_write_max_size: 00277 if (!success) { 00278 handle_error(NFC_ERR_CONTROLLER); 00279 return; 00280 } 00281 00282 // Start erasing bytes 00283 _current_op = nfc_eeprom_erase_erase_bytes; 00284 continue_erase(); 00285 break; 00286 case nfc_eeprom_erase_write_0_size: 00287 if (!success) { 00288 handle_error(NFC_ERR_CONTROLLER); 00289 return; 00290 } 00291 00292 // End session 00293 _current_op = nfc_eeprom_erase_end_session; 00294 _operation_result = NFC_OK; 00295 _driver->end_session(); 00296 break; 00297 default: 00298 // Should not happen, state machine is broken or driver is doing something wrong 00299 handle_error(NFC_ERR_UNKNOWN); 00300 return; 00301 } 00302 } 00303 00304 void NFCEEPROM::on_size_read(bool success, size_t size) 00305 { 00306 switch (_current_op) { 00307 case nfc_eeprom_read_read_size: { 00308 if (!success) { 00309 handle_error(NFC_ERR_CONTROLLER); 00310 return; 00311 } 00312 00313 // Reset NDEF message buffer builder 00314 ac_buffer_builder_t *buffer_builder = ndef_msg_buffer_builder(ndef_message()); 00315 ac_buffer_builder_reset(buffer_builder); 00316 00317 // Check that we have a big enough buffer to read the message 00318 if (size > ac_buffer_builder_writable(buffer_builder)) { 00319 // Not enough space, close session 00320 _current_op = nfc_eeprom_read_end_session; 00321 _operation_result = NFC_ERR_BUFFER_TOO_SMALL; 00322 _driver->end_session(); 00323 return; 00324 } 00325 00326 // Save size and reset address 00327 _eeprom_address = 0; 00328 _ndef_buffer_read_sz = size; 00329 00330 // Start reading bytes 00331 _current_op = nfc_eeprom_read_read_bytes; 00332 _event_queue->call(this, &NFCEEPROM::continue_read); 00333 break; 00334 } 00335 default: 00336 // Should not happen, state machine is broken or driver is doing something wrong 00337 handle_error(NFC_ERR_UNKNOWN); 00338 return; 00339 } 00340 } 00341 00342 void NFCEEPROM::on_bytes_erased(size_t count) 00343 { 00344 00345 switch (_current_op) { 00346 case nfc_eeprom_erase_erase_bytes: 00347 if (count == 0) { 00348 handle_error(NFC_ERR_CONTROLLER); 00349 return; 00350 } 00351 00352 // Update address 00353 _eeprom_address += count; 00354 00355 // Continue erasing 00356 _event_queue->call(this, &NFCEEPROM::continue_erase); 00357 break; 00358 default: 00359 // Should not happen, state machine is broken or driver is doing something wrong 00360 handle_error(NFC_ERR_UNKNOWN); 00361 return; 00362 } 00363 } 00364 00365 void NFCEEPROM::continue_write() 00366 { 00367 if (ac_buffer_reader_readable(&_ndef_buffer_reader) > 0) { 00368 // Continue writing 00369 _driver->write_bytes(_eeprom_address, ac_buffer_reader_current_buffer_pointer(&_ndef_buffer_reader), ac_buffer_reader_current_buffer_length(&_ndef_buffer_reader)); 00370 } else { 00371 // we are done 00372 _current_op = nfc_eeprom_write_end_session; 00373 _operation_result = NFC_OK; 00374 _driver->end_session(); 00375 } 00376 } 00377 00378 void NFCEEPROM::continue_erase() 00379 { 00380 if (_eeprom_address < _driver->read_max_size()) { 00381 // Continue erasing 00382 _driver->erase_bytes(_eeprom_address, _driver->read_max_size() - _eeprom_address); 00383 } else { 00384 // Now update size 00385 _current_op = nfc_eeprom_erase_write_0_size; 00386 _driver->write_size(0); 00387 } 00388 } 00389 00390 void NFCEEPROM::continue_read() 00391 { 00392 if (_eeprom_address < _ndef_buffer_read_sz) { 00393 // Continue reading 00394 ac_buffer_builder_t *buffer_builder = ndef_msg_buffer_builder(ndef_message()); 00395 _driver->read_bytes(_eeprom_address, ac_buffer_builder_write_position(buffer_builder), _ndef_buffer_read_sz - _eeprom_address); 00396 } else { 00397 // Done, close session 00398 _current_op = nfc_eeprom_read_end_session; 00399 _operation_result = NFC_OK; 00400 _driver->end_session(); 00401 } 00402 } 00403 00404 void NFCEEPROM::handle_error(nfc_err_t ret) 00405 { 00406 // Save & reset current op 00407 nfc_eeprom_operation_t last_op = _current_op; 00408 _current_op = nfc_eeprom_idle; 00409 00410 if (_delegate != NULL) { 00411 if (last_op <= nfc_eeprom_write_end_session) { 00412 _delegate->on_ndef_message_written(ret); 00413 } else if (last_op <= nfc_eeprom_read_end_session) { 00414 _delegate->on_ndef_message_read(ret); 00415 } else if (last_op <= nfc_eeprom_erase_end_session) { 00416 _delegate->on_ndef_message_erased(ret); 00417 } 00418 } 00419 } 00420 00421 NFCNDEFCapable::Delegate *NFCEEPROM::ndef_capable_delegate() 00422 { 00423 return _delegate; 00424 }
Generated on Tue Jul 12 2022 13:54:38 by
