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.
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_bytes; 00142 continue_write(); 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 // End session 00276 _current_op = nfc_eeprom_write_end_session; 00277 _operation_result = NFC_OK; 00278 _driver->end_session(); 00279 break; 00280 case nfc_eeprom_erase_write_max_size: 00281 if (!success) { 00282 handle_error(NFC_ERR_CONTROLLER); 00283 return; 00284 } 00285 00286 // Start erasing bytes 00287 _current_op = nfc_eeprom_erase_erase_bytes; 00288 continue_erase(); 00289 break; 00290 case nfc_eeprom_erase_write_0_size: 00291 if (!success) { 00292 handle_error(NFC_ERR_CONTROLLER); 00293 return; 00294 } 00295 00296 // End session 00297 _current_op = nfc_eeprom_erase_end_session; 00298 _operation_result = NFC_OK; 00299 _driver->end_session(); 00300 break; 00301 default: 00302 // Should not happen, state machine is broken or driver is doing something wrong 00303 handle_error(NFC_ERR_UNKNOWN); 00304 return; 00305 } 00306 } 00307 00308 void NFCEEPROM::on_size_read(bool success, size_t size) 00309 { 00310 switch (_current_op) { 00311 case nfc_eeprom_read_read_size: { 00312 if (!success) { 00313 handle_error(NFC_ERR_CONTROLLER); 00314 return; 00315 } 00316 00317 // Reset NDEF message buffer builder 00318 ac_buffer_builder_t *buffer_builder = ndef_msg_buffer_builder(ndef_message()); 00319 ac_buffer_builder_reset(buffer_builder); 00320 00321 // Check that we have a big enough buffer to read the message 00322 if (size > ac_buffer_builder_writable(buffer_builder)) { 00323 // Not enough space, close session 00324 _current_op = nfc_eeprom_read_end_session; 00325 _operation_result = NFC_ERR_BUFFER_TOO_SMALL; 00326 _driver->end_session(); 00327 return; 00328 } 00329 00330 // Save size and reset address 00331 _eeprom_address = 0; 00332 _ndef_buffer_read_sz = size; 00333 00334 // Start reading bytes 00335 _current_op = nfc_eeprom_read_read_bytes; 00336 continue_read(); 00337 break; 00338 } 00339 default: 00340 // Should not happen, state machine is broken or driver is doing something wrong 00341 handle_error(NFC_ERR_UNKNOWN); 00342 return; 00343 } 00344 } 00345 00346 void NFCEEPROM::on_bytes_erased(size_t count) 00347 { 00348 switch (_current_op) { 00349 case nfc_eeprom_erase_erase_bytes: 00350 if (count == 0) { 00351 handle_error(NFC_ERR_CONTROLLER); 00352 return; 00353 } 00354 00355 // Update address 00356 _eeprom_address += count; 00357 00358 // Continue erasing 00359 continue_erase(); 00360 break; 00361 default: 00362 // Should not happen, state machine is broken or driver is doing something wrong 00363 handle_error(NFC_ERR_UNKNOWN); 00364 return; 00365 } 00366 } 00367 00368 void NFCEEPROM::continue_write() 00369 { 00370 if (ac_buffer_reader_readable(&_ndef_buffer_reader) > 0) { 00371 // Continue writing 00372 _driver->write_bytes(_eeprom_address, ac_buffer_reader_current_buffer_pointer(&_ndef_buffer_reader), ac_buffer_reader_current_buffer_length(&_ndef_buffer_reader)); 00373 } else { 00374 // Now update size 00375 _current_op = nfc_eeprom_write_write_size; 00376 _driver->write_size(_eeprom_address); 00377 } 00378 } 00379 00380 void NFCEEPROM::continue_erase() 00381 { 00382 if (_eeprom_address < _driver->read_max_size()) { 00383 // Continue erasing 00384 _driver->erase_bytes(_eeprom_address, _driver->read_max_size() - _eeprom_address); 00385 } else { 00386 // Now update size 00387 _current_op = nfc_eeprom_erase_write_0_size; 00388 _driver->write_size(0); 00389 } 00390 } 00391 00392 void NFCEEPROM::continue_read() 00393 { 00394 if (_eeprom_address < _ndef_buffer_read_sz) { 00395 // Continue reading 00396 ac_buffer_builder_t *buffer_builder = ndef_msg_buffer_builder(ndef_message()); 00397 _driver->read_bytes(_eeprom_address, ac_buffer_builder_write_position(buffer_builder), _ndef_buffer_read_sz - _eeprom_address); 00398 } else { 00399 // Done, close session 00400 _current_op = nfc_eeprom_read_end_session; 00401 _operation_result = NFC_OK; 00402 _driver->end_session(); 00403 } 00404 } 00405 00406 void NFCEEPROM::handle_error(nfc_err_t ret) 00407 { 00408 // Save & reset current op 00409 nfc_eeprom_operation_t last_op = _current_op; 00410 _current_op = nfc_eeprom_idle; 00411 00412 if (_delegate != NULL) { 00413 if (last_op <= nfc_eeprom_write_end_session) { 00414 _delegate->on_ndef_message_written(ret); 00415 } else if (last_op <= nfc_eeprom_read_end_session) { 00416 _delegate->on_ndef_message_read(ret); 00417 } else if (last_op <= nfc_eeprom_erase_end_session) { 00418 _delegate->on_ndef_message_erased(ret); 00419 } 00420 } 00421 } 00422 00423 NFCNDEFCapable::Delegate *NFCEEPROM::ndef_capable_delegate() 00424 { 00425 return _delegate; 00426 }
Generated on Tue Aug 9 2022 00:37:16 by
 1.7.2
 1.7.2