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.
Dependencies: nRF51_Vdd TextLCD BME280
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 }
Generated on Tue Jul 12 2022 15:15:54 by
