Mbed OS Reference
Loading...
Searching...
No Matches
m24sr_driver.h
1/* mbed Microcontroller Library
2 * SPDX-License-Identifier: BSD-3-Clause
3 ******************************************************************************
4 * @file m24sr_driver.h
5 * @author ST Central Labs
6 * @brief This file provides a set of functions to interface with the M24SR
7 * device.
8 ******************************************************************************
9 * @attention
10 *
11 * <h2><center>&copy; COPYRIGHT(c) 2018 STMicroelectronics</center></h2>
12 *
13 * Redistribution and use in source and binary forms, with or without modification,
14 * are permitted provided that the following conditions are met:
15 * 1. Redistributions of source code must retain the above copyright notice,
16 * this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright notice,
18 * this list of conditions and the following disclaimer in the documentation
19 * and/or other materials provided with the distribution.
20 * 3. Neither the name of STMicroelectronics nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 *
35 ******************************************************************************
36 */
37
38/*
39 Based on: X-CUBE-MEMS1/trunk/Drivers/BSP/Components/m24sr/m24sr.h
40 Revision: M24SR Driver V1.0.0
41 */
42
43#ifndef M24SR_H
44#define M24SR_H
45
46#include <stdint.h>
47#include <mbed.h>
48#include "I2C.h"
49#include "NFCEEPROMDriver.h"
50#include "EventQueue.h"
51
52#if defined TARGET_DISCO_L475VG_IOT01A
53
54#define M24SR_I2C_SDA_PIN PB_11
55#define M24SR_I2C_SCL_PIN PB_10
56#define M24SR_GPO_PIN PE_4
57#define M24SR_RF_DISABLE_PIN PE_2
58
59#elif MBED_CONF_X_NUCLEO_NFC01A1
60
61#define M24SR_I2C_SDA_PIN D14
62#define M24SR_I2C_SCL_PIN D15
63#define M24SR_GPO_PIN D12
64#define M24SR_RF_DISABLE_PIN D11
65
66#else
67
68#define M24SR_I2C_SDA_PIN NC
69#define M24SR_I2C_SCL_PIN NC
70#define M24SR_GPO_PIN NC
71#define M24SR_RF_DISABLE_PIN NC
72
73#endif
74
75namespace mbed {
76namespace nfc {
77namespace vendor {
78namespace ST {
79
80#define OPEN_SESSION_RETRIES 5
81#define CC_FILE_LENGTH 15
82#define NDEF_FILE_HEADER_SIZE 2
83#define MAX_NDEF_SIZE 0x1FFF
84
85/**
86 * User parameter used to invoke a command,
87 * it is used to provide the data back with the response
88 */
90 uint8_t *data; /**< data */
91 uint16_t length; /**< number of bytes in the data array */
92 uint16_t offset; /**< offset parameter used in the read/write command */
93};
94
95/**
96 * @brief APDU Command structure
97 */
98class C_APDU {
99public:
101 uint8_t CLA; /**< Command class */
102 uint8_t INS; /**< Operation code */
103 uint8_t P1; /**< Selection Mode */
104 uint8_t P2; /**< Selection Option */
105 };
106
108 uint8_t LC; /**< Data field length */
109 const uint8_t *data; /**< Command parameters */
110 uint8_t LE; /**< Expected length of data to be returned */
111 };
112
113 C_APDU(uint8_t cla, uint8_t ins, uint16_t p1p2, uint8_t length, const uint8_t *data, uint8_t expected)
114 {
115 header.CLA = cla;
116 header.INS = ins;
117 header.P1 = (uint8_t)((p1p2 & 0xFF00) >> 8);
118 header.P2 = (uint8_t)(p1p2 & 0x00FF);
119 body.LC = length;
120 body.data = data;
121 body.LE = expected;
122 }
123
124 C_APDUHeader_t header;
125 C_APDUBody_t body;
126};
127
128/**
129 * @brief SC response structure
130 */
131struct R_APDU {
132 uint8_t *data; /**< Data returned from the card */ // pointer on the transceiver buffer = ReaderRecBuf[CR95HF_DATA_OFFSET ];
133 uint8_t SW1; /**< Command Processing status */
134 uint8_t SW2; /**< Command Processing qualification */
135};
136
137enum M24srError_t : uint16_t {
138 M24SR_SUCCESS = 0,
139 M24SR_ERROR = 0x6F00,
140 M24SR_FILE_OVERFLOW_LE = 0x6280,
141 M24SR_EOF = 0x6282,
142 M24SR_PASSWORD_REQUIRED = 0x6300,
143 M24SR_PASSWORD_INCORRECT = 0x63C0,
144 M24SR_PASSWORD_INCORRECT1RETRY = 0x63C1,
145 M24SR_PASSWORD_INCORRECT2RETRY = 0x63C2,
146 M24SR_WRONG_LENGHT = 0x6700,
147 M24SR_UNSUCESSFUL_UPDATING = 0x6581,
148 M24SR_INCOPATIBLE_COMMAND = 0x6981,
149 M24SR_SECURITY_UNSATISFIED = 0x6982,
150 M24SR_REFERENCE_DATA_NOT_USABLE = 0x6984,
151
152 M24SR_INCORRECT_PARAMETER = 0x6a80,
153 M24SR_FILE_NOT_FOUND = 0x6a82,
154 M24SR_FILE_OVERFLOW_LC = 0x6A84,
155
156 M24SR_INCORRECT_P1_OR_P2 = 0x6A86,
157 M24SR_RF_SESSION_KILLED = 0x6500,
158 M24SR_INS_NOT_SUPPORTED = 0x6D00,
159 M24SR_CLASS_NOT_SUPPORTED = 0x6E00,
160
161 M24SR_IO_ERROR_I2CTIMEOUT = 0x0011,
162 M24SR_IO_ERROR_CRC = 0x0012,
163 M24SR_IO_ERROR_NACK = 0x0013,
164 M24SR_IO_ERROR_PARAMETER = 0x0014,
165 M24SR_IO_ERROR_NBATEMPT = 0x0015,
166 M24SR_IO_NOACKNOWLEDGE = 0x0016,
167 M24SR_IO_PIN_NOT_CONNECTED = 0x0017
168};
169
170/**
171 * @brief GPO state
172 */
173enum NfcGpoState_t {
174 HIGH_IMPEDANCE = 0,
175 SESSION_OPENED = 1,
176 WIP = 2,
177 I2C_ANSWER_READY = 3,
178 INTERRUPT = 4,
179 STATE_CONTROL = 5
180};
181
182/**
183 * Possible password to set.
184 */
185enum PasswordType_t {
186 READ_PASSWORD = 0x01, /**< Password to use before reading the tag */
187 WRITE_PASSWORD = 0x02, /**< Password to use before writing the tag */
188 I2C_PASSWORD = 0x03, /**< Root password, used only through nfc */
189};
190
191/**
192 * Command that the component can accept
193 */
194enum Command_t {
195 NONE,
196 DESELECT,
197 SELECT_APPLICATION,
198 SELECT_CC_FILE,
199 SELECT_NDEF_FILE,
200 SELECT_SYSTEM_FILE,
201 READ,
202 UPDATE,
203 VERIFY,
204 MANAGE_I2C_GPO,
205 MANAGE_RF_GPO,
206 CHANGE_REFERENCE_DATA,
207 ENABLE_VERIFICATION_REQUIREMENT,
208 DISABLE_VERIFICATION_REQUIREMENT,
209 ENABLE_PERMANET_STATE,
210 DISABLE_PERMANET_STATE,
211};
212
213/**
214 * Communication mode used by this device
215 */
216enum Communication_t {
217 SYNC, /**< SYNC wait the command response before returning */
218 ASYNC /**< ASYNC use a callback to notify the end of a command */
219};
220
221/**
222 * Class representing a M24SR component.
223 * This component has two operation modes, sync or async.
224 * In sync mode each function call returns only after the command has completed.
225 * In async mode each function call returns immediately and the answer will be notified
226 * through a callback.
227 * The default behaviour is sync mode.
228 */
230public:
231 /**
232 * Object that contains all the callbacks fired by this class, each command has its own callback.
233 * The callback default implementation is an empty function.
234 */
235 class Callbacks {
236 public:
237 /** called when get_session completes */
238 virtual void on_session_open(M24srDriver *nfc, M24srError_t status)
239 {
240 (void) nfc;
241 (void) status;
242 }
243
244 /** called when deselect completes */
245 virtual void on_deselect(M24srDriver *nfc, M24srError_t status)
246 {
247 (void) nfc;
248 (void) status;
249 }
250
251 /** called when select_application completes */
252 virtual void on_selected_application(M24srDriver *nfc, M24srError_t status)
253 {
254 (void) nfc;
255 (void) status;
256 }
257
258 /** called when select_cc_file completes */
259 virtual void on_selected_cc_file(M24srDriver *nfc, M24srError_t status)
260 {
261 (void) nfc;
262 (void) status;
263 }
264
265 /** called when select_ndef_file completes */
266 virtual void on_selected_ndef_file(M24srDriver *nfc, M24srError_t status)
267 {
268 (void) nfc;
269 (void) status;
270 }
271
272 /** called when select_system_file completes */
273 virtual void on_selected_system_file(M24srDriver *nfc, M24srError_t status)
274 {
275 (void) nfc;
276 (void) status;
277 }
278
279 /** called when read_binary completes */
280 virtual void on_read_byte(M24srDriver *nfc, M24srError_t status, uint16_t offset, uint8_t *bytes_read,
281 uint16_t read_count)
282 {
283 (void) nfc;
284 (void) status;
285 (void) offset;
286 (void) bytes_read;
287 (void) read_count;
288 }
289
290 /** called when update_binary completes */
291 virtual void on_updated_binary(M24srDriver *nfc, M24srError_t status, uint16_t offset, uint8_t *bytes_written,
292 uint16_t write_count)
293 {
294 (void) nfc;
295 (void) status;
296 (void) bytes_written;
297 (void) write_count;
298 (void) offset;
299 }
300
301 /** called when verify completes */
302 virtual void on_verified(M24srDriver *nfc, M24srError_t status, PasswordType_t password_type, const uint8_t *pwd)
303 {
304 (void) nfc;
305 (void) status;
306 (void) password_type;
307 (void) pwd;
308 }
309
310 /** called when manage_i2c_gpo completes */
311 virtual void on_manage_i2c_gpo(M24srDriver *nfc, M24srError_t status, NfcGpoState_t new_status)
312 {
313 (void) nfc;
314 (void) status;
315 (void) new_status;
316 }
317
318 /** called when manage_rf_gpo completes */
319 virtual void on_manage_rf_gpo(M24srDriver *nfc, M24srError_t status, NfcGpoState_t new_status)
320 {
321 (void) nfc;
322 (void) status;
323 (void) new_status;
324 }
325
326 /** called when change_reference_data completes */
327 virtual void on_change_reference_data(M24srDriver *nfc, M24srError_t status, PasswordType_t type,
328 const uint8_t *data)
329 {
330 (void) nfc;
331 (void) status;
332 (void) type;
333 (void) data;
334 }
335
336 /** called when enable_verification_requirement completes */
337 virtual void on_enable_verification_requirement(M24srDriver *nfc, M24srError_t status, PasswordType_t type)
338 {
339 (void) nfc;
340 (void) status;
341 (void) type;
342 }
343
344 /** called when disable_verification_requirement completes */
345 virtual void on_disable_verification_requirement(M24srDriver *nfc, M24srError_t status, PasswordType_t type)
346 {
347 (void) nfc;
348 (void) status;
349 (void) type;
350 }
351
352 /** called when enable_permanent_state completes */
353 virtual void on_enable_permanent_state(M24srDriver *nfc, M24srError_t status, PasswordType_t type)
354 {
355 (void) nfc;
356 (void) status;
357 (void) type;
358 }
359
360 /** called when disable_permanent_state completes */
361 virtual void on_disable_permanent_state(M24srDriver *nfc, M24srError_t status, PasswordType_t type)
362 {
363 (void) nfc;
364 (void) status;
365 (void) type;
366 }
367
368 /** called when read_id completes */
369 virtual void on_read_id(M24srDriver *nfc, M24srError_t status, uint8_t *id)
370 {
371 (void) nfc;
372 (void) status;
373 (void) id;
374 }
375
376 /** called when enable_read_password completes */
377 virtual void on_enable_read_password(M24srDriver *nfc, M24srError_t status, const uint8_t *new_password)
378 {
379 (void) nfc;
380 (void) status;
381 (void) new_password;
382 }
383
384 /** called when oenable_write_password completes */
385 virtual void on_enable_write_password(M24srDriver *nfc, M24srError_t status, const uint8_t *new_password)
386 {
387 (void) nfc;
388 (void) status;
389 (void) new_password;
390 }
391
392 /** called when disable_read_password completes */
393 virtual void on_disable_read_password(M24srDriver *nfc, M24srError_t status)
394 {
395 (void) nfc;
396 (void) status;
397 }
398
399 /** called when disable_write_password completes */
400 virtual void on_disable_write_password(M24srDriver *nfc, M24srError_t status)
401 {
402 (void) nfc;
403 (void) status;
404 }
405
406 /** called when disable_all_password completes */
407 virtual void on_disable_all_password(M24srDriver *nfc, M24srError_t status)
408 {
409 (void) nfc;
410 (void) status;
411 }
412
413 /** called when enable_read_only completes */
414 virtual void on_enable_read_only(M24srDriver *nfc, M24srError_t status)
415 {
416 (void) nfc;
417 (void) status;
418 }
419
420 /** called when enable_write_only completes */
421 virtual void on_enable_write_only(M24srDriver *nfc, M24srError_t status)
422 {
423 (void) nfc;
424 (void) status;
425 }
426
427 /** called when disable_read_only completes */
428 virtual void on_disable_read_only(M24srDriver *nfc, M24srError_t status)
429 {
430 (void) nfc;
431 (void) status;
432 }
433
434 /** called when disable_write_only completes */
435 virtual void on_disable_write_only(M24srDriver *nfc, M24srError_t status)
436 {
437 (void) nfc;
438 (void) status;
439 }
440
441 virtual ~Callbacks() { }
442 };
443
444public:
445 /** Create the driver, default pin names will be used appropriate for the board.
446 * @param i2c_data_pin I2C data pin name.
447 * @param i2c_clock_pin I2C clock pin name.
448 * @param gpo_pin I2C GPO pin name.
449 * @param rf_disable_pin pin name for breaking the RF connection.
450 */
451 M24srDriver(PinName i2c_data_pin = M24SR_I2C_SDA_PIN, PinName i2c_clock_pin = M24SR_I2C_SCL_PIN,
452 PinName gpo_pin = M24SR_GPO_PIN, PinName rf_disable_pin = M24SR_RF_DISABLE_PIN);
453
454 virtual ~M24srDriver() { }
455
456 /** @see NFCEEPROMDriver::reset
457 */
458 virtual void reset()
459 {
460 set_callback(&_default_cb);
461 init();
462 manage_i2c_gpo(I2C_ANSWER_READY);
463 }
464
465 /** @see NFCEEPROMDriver::get_max_size
466 */
467 virtual size_t read_max_size()
468 {
469 return MAX_NDEF_SIZE;
470 }
471
472 /** @see NFCEEPROMDriver::start_session
473 */
474 virtual void start_session(bool force = true)
475 {
476 if (_is_session_open) {
477 delegate()->on_session_started(true);
478 return;
479 }
480
481 set_callback(&_open_session_cb);
482
483 get_session(force);
484 }
485
486 /** @see NFCEEPROMDriver::end_session
487 */
488 virtual void end_session()
489 {
490 set_callback(&_close_session_cb);
491 deselect();
492 }
493
494 /** @see NFCEEPROMDriver::read_bytes
495 */
496 virtual void read_bytes(uint32_t address, uint8_t *bytes, size_t count)
497 {
498 if (!_is_session_open) {
499 delegate()->on_bytes_read(0);
500 return;
501 }
502
503 if (address > _ndef_size) {
504 delegate()->on_bytes_read(0);
505 return;
506 }
507
508 set_callback(&_read_byte_cb);
509
510 if (count > _max_read_bytes) {
511 count = _max_read_bytes;
512 }
513
514 if (address + count > _ndef_size) {
515 count = _ndef_size - address;
516 }
517
518 if (count == 0) {
519 delegate()->on_bytes_read(0);
520 return;
521 }
522
523 /* offset by ndef file size*/
524 address += NDEF_FILE_HEADER_SIZE;
525
526 read_binary((uint16_t) address, (uint8_t) count, bytes);
527 }
528
529 /** @see NFCEEPROMDriver::write_bytes
530 */
531 virtual void write_bytes(uint32_t address, const uint8_t *bytes, size_t count)
532 {
533 if (!_is_session_open) {
534 delegate()->on_bytes_written(0);
535 return;
536 }
537
538 if (address > _ndef_size) {
539 delegate()->on_bytes_written(0);
540 return;
541 }
542
543 if (bytes) {
544 set_callback(&_write_byte_cb);
545 } else {
546 set_callback(&_erase_bytes_cb);
547 }
548
549 if (count > _max_write_bytes) {
550 count = _max_write_bytes;
551 }
552
553 if (address + count > _ndef_size) {
554 count = _ndef_size - address;
555 }
556
557 if (count == 0) {
558 delegate()->on_bytes_written(0);
559 return;
560 }
561
562 /* offset by ndef file size*/
563 address += NDEF_FILE_HEADER_SIZE;
564
565 update_binary((uint16_t) address, (uint8_t) count, bytes);
566 }
567
568 /** @see NFCEEPROMDriver::set_size
569 */
570 virtual void write_size(size_t count)
571 {
572 if (!_is_session_open) {
573 delegate()->on_size_read(false, 0);
574 return;
575 }
576
577 if (count > MAX_NDEF_SIZE - NDEF_FILE_HEADER_SIZE) {
578 delegate()->on_size_read(false, 0);
579 return;
580 }
581
582 set_callback(&_set_size_cb);
583
584 _ndef_size = (uint16_t)count;
585
586 /* NDEF file size is BE */
587 uint8_t *bytes = (uint8_t *)&_ndef_size;
588 _ndef_size_buffer[0] = bytes[1];
589 _ndef_size_buffer[1] = bytes[0];
590
591 update_binary(0, NDEF_FILE_HEADER_SIZE, (const uint8_t *)&_ndef_size_buffer);
592 }
593
594 /** @see NFCEEPROMDriver::get_size
595 */
596 virtual void read_size()
597 {
598 if (!_is_session_open) {
599 delegate()->on_size_read(false, 0);
600 return;
601 }
602
603 set_callback(&_get_size_cb);
604
605 read_binary(0, NDEF_FILE_HEADER_SIZE, (uint8_t *)&_ndef_size_buffer);
606 }
607
608 /** @see NFCEEPROMDriver::erase_bytes
609 */
610 virtual void erase_bytes(uint32_t address, size_t size)
611 {
612 write_bytes(address, NULL, size);
613 }
614
615private:
616 /**
617 * Change the function to call when a command ends.
618 * @param commandCallback Object containing the callback, if NULL it will use empty callback
619 */
620 void set_callback(Callbacks *callback)
621 {
622 if (callback) {
623 _command_cb = callback;
624 } else {
625 _command_cb = &_default_cb;
626 }
627 }
628
629 /**
630 * get the callback object to use
631 * @return callback object to use
632 */
633 Callbacks *get_callback()
634 {
635 /* this allows for two levels of operation, the previous command will continue
636 * when this set of callbacks has finished */
637 if (_subcommand_cb) {
638 return _subcommand_cb;
639 }
640 return _command_cb;
641 }
642
643 void nfc_interrupt_callback()
644 {
645 if (_communication_type == ASYNC) {
646 event_queue()->call(this, &M24srDriver::manage_event);
647 }
648 }
649
650 /**
651 * Enable the request of a password before reading the tag.
652 * @param current_write_password Current password
653 * @param new_password Password to request before reading the tag.
654 * @return return M24SR_SUCCESS if no errors
655 * @note The password must have a length of 16 chars.
656 */
657 M24srError_t enable_read_password(const uint8_t *current_write_password, const uint8_t *new_password)
658 {
659 _subcommand_cb = &_change_password_request_status_cb;
660 _change_password_request_status_cb.set_task(READ_PASSWORD, new_password);
661
662 return verify(WRITE_PASSWORD, current_write_password);
663 }
664
665 /**
666 * Disable the request of a password before reading the tag.
667 * @param current_write_password Current password
668 * @return return M24SR_SUCCESS if no errors
669 * @note The password must have a length of 16 chars.
670 */
671 M24srError_t disable_read_password(const uint8_t *current_write_password)
672 {
673 _subcommand_cb = &_change_password_request_status_cb;
674 _change_password_request_status_cb.set_task(READ_PASSWORD, NULL);
675
676 return verify(WRITE_PASSWORD, current_write_password);
677 }
678
679 /**
680 * Enable the request of a password before writing to the tag.
681 * @param current_write_password Current password
682 * @param new_password Password to request before reading the tag.
683 * @return return M24SR_SUCCESS if no errors
684 * @note The password must have a length of 16 chars.
685 */
686 M24srError_t enable_write_password(const uint8_t *current_write_password, uint8_t *new_password)
687 {
688 _subcommand_cb = &_change_password_request_status_cb;
689 _change_password_request_status_cb.set_task(WRITE_PASSWORD, new_password);
690
691 return verify(WRITE_PASSWORD, current_write_password);
692 }
693
694 /**
695 * Disable the request of a password before writing the tag.
696 * @param current_write_password Current password.
697 * @return return M24SR_SUCCESS if no errors
698 * @note The password must have a length of 16 chars.
699 */
700 M24srError_t disable_write_password(const uint8_t *current_write_password)
701 {
702 _subcommand_cb = &_change_password_request_status_cb;
703 _change_password_request_status_cb.set_task(WRITE_PASSWORD, NULL);
704
705 return verify(WRITE_PASSWORD, current_write_password);
706 }
707
708 /**
709 * @brief This function disables both read and write passwords.
710 * @param super_user_password I2C super user password.
711 * @return return M24SR_SUCCESS if no errors
712 * @note The password must have a length of 16 chars.
713 */
714 M24srError_t disable_all_password(const uint8_t *super_user_password)
715 {
716 _subcommand_cb = &_remove_password_cb;
717 return verify(I2C_PASSWORD, super_user_password);
718 }
719
720 /**
721 * @brief This function enables read only mode.
722 * @param current_write_password Write password is needed to enable read only mode.
723 * @return return M24SR_SUCCESS if no errors
724 * @note The password must have a length of 16 chars.
725 */
726 M24srError_t enable_read_only(const uint8_t *current_write_password)
727 {
728 _subcommand_cb = &_change_access_state_cb;
729 _change_access_state_cb.change_access_state(ChangeAccessStateCallback::WRITE, false);
730
731 return verify(WRITE_PASSWORD, current_write_password);
732 }
733
734 /**
735 * @brief This function disables read only mode.
736 * @param current_write_password Write password is needed to disable read only mode.
737 * @return return M24SR_SUCCESS if no errors
738 * @note The password must have a length of 16 chars.
739 */
740 M24srError_t disable_read_only(const uint8_t *current_write_password)
741 {
742 _subcommand_cb = &_change_access_state_cb;
743 _change_access_state_cb.change_access_state(ChangeAccessStateCallback::WRITE, true);
744
745 return verify(I2C_PASSWORD, current_write_password);
746 }
747
748 /**
749 * @brief This function enables write only mode.
750 * @param current_write_password Write password is needed to enable write only mode.
751 * @return return M24SR_SUCCESS if no errors
752 * @note The password must have a length of 16 chars.
753 */
754 M24srError_t enable_write_only(const uint8_t *current_write_password)
755 {
756 _subcommand_cb = &_change_access_state_cb;
757 _change_access_state_cb.change_access_state(ChangeAccessStateCallback::READ, false);
758
759 return verify(WRITE_PASSWORD, current_write_password);
760 }
761
762 /**
763 * @brief This function disables write only mode.
764 * @param current_write_password Write password is needed to disable write only mode.
765 * @return return M24SR_SUCCESS if no errors
766 * @note The password must have a length of 16 chars.
767 */
768 M24srError_t disable_write_only(const uint8_t *current_write_password)
769 {
770 _subcommand_cb = &_change_access_state_cb;
771 _change_access_state_cb.change_access_state(ChangeAccessStateCallback::READ, true);
772
773 return verify(I2C_PASSWORD, current_write_password);
774 }
775
776private:
777 M24srError_t init();
778 M24srError_t read_id(uint8_t *nfc_id);
779 M24srError_t get_session(bool force = false);
780
781 M24srError_t deselect();
782 M24srError_t receive_deselect();
783
784 M24srError_t select_application();
785 M24srError_t receive_select_application();
786
787 M24srError_t select_cc_file();
788 M24srError_t receive_select_cc_file();
789
790 M24srError_t select_ndef_file(uint16_t ndef_file_id);
791 M24srError_t receive_select_ndef_file();
792
793 M24srError_t select_system_file();
794 M24srError_t receive_select_system_file();
795
796 M24srError_t read_binary(uint16_t offset, uint8_t length, uint8_t *buffer);
797 M24srError_t st_read_binary(uint16_t offset, uint8_t length, uint8_t *buffer);
798 M24srError_t receive_read_binary();
799
800 M24srError_t update_binary(uint16_t offset, uint8_t length, const uint8_t *data);
801 M24srError_t receive_update_binary();
802
803 M24srError_t verify(PasswordType_t password_type, const uint8_t *password);
804 M24srError_t receive_verify();
805
806 M24srError_t change_reference_data(PasswordType_t password_type, const uint8_t *password);
807 M24srError_t receive_change_reference_data();
808
809 M24srError_t enable_verification_requirement(PasswordType_t password_type);
810 M24srError_t receive_enable_verification_requirement();
811
812 M24srError_t disable_verification_requirement(PasswordType_t password_type);
813 M24srError_t receive_disable_verification_requirement();
814
815 M24srError_t enable_permanent_state(PasswordType_t password_type);
816 M24srError_t receive_enable_permanent_state();
817
818 M24srError_t disable_permanent_state(PasswordType_t password_type);
819 M24srError_t receive_disable_permanent_state();
820
821 M24srError_t send_interrupt();
822 M24srError_t state_control(bool gpo_reset);
823
824 M24srError_t manage_i2c_gpo(NfcGpoState_t gpo_i2c_config);
825 M24srError_t manage_rf_gpo(NfcGpoState_t gpo_rf_config);
826
827 M24srError_t rf_config(bool enable);
828 M24srError_t send_fwt_extension(uint8_t fwt_byte);
829
830 M24srError_t send_receive_i2c(uint16_t length, uint8_t *command);
831
832 /**
833 * Function to call when the component fire an interrupt.
834 * @return last operation status
835 */
836 M24srError_t manage_event();
837
838 /**
839 * Send a command to the component.
840 * @param length Length of the command.
841 * @param command Buffer containing the command.
842 * @return M24SR_SUCCESS if no errors
843 */
844 M24srError_t io_send_i2c_command(uint8_t length, const uint8_t *command);
845
846 /**
847 * Read a command response.
848 * @param length Number of bytes to read.
849 * @param command Buffer to store the response into.
850 * @return M24SR_SUCCESS if no errors
851 */
852 M24srError_t io_receive_i2c_response(uint8_t length, uint8_t *command);
853
854 /**
855 * Do an active polling on the I2C bus until the answer is ready.
856 * @return M24SR_SUCCESS if no errors
857 */
858 M24srError_t io_poll_i2c();
859
860 bool manage_sync_communication(M24srError_t *status);
861
862private:
863 /**
864 * @brief This class permits to enable/disable the password request to read/write into the tag
865 */
866 class ChangePasswordRequestStatusCallback : public Callbacks {
867 public:
868 /**
869 * Build the chain of callbacks.
870 */
871 ChangePasswordRequestStatusCallback()
872 : _new_password(NULL),
873 _type(I2C_PASSWORD),
874 _enable(false) { }
875
876 /* This class is equivalent to calling the methods:
877 *
878 * To enable the request:
879 * - Verify
880 * - change_reference_data
881 * - enable_permanent_state
882 *
883 * To disable the request:
884 * - verify
885 * - disable_verification_requirement
886 */
887
888 /**
889 * Set the password to enable/disable.
890 * @param type Type of password to enable/disable.
891 * @param new_password Array of 16bytes with the new password, if null the request will be disabled.
892 */
893 void set_task(PasswordType_t type, const uint8_t *new_password)
894 {
895 _new_password = new_password;
896 _type = type;
897 _enable = (new_password != NULL);
898 }
899
900 virtual void on_verified(M24srDriver *nfc, M24srError_t status, PasswordType_t, const uint8_t *)
901 {
902 if (status != M24SR_SUCCESS) {
903 return on_finish_command(nfc, status);
904 }
905 if (_enable) {
906 nfc->change_reference_data(_type, _new_password);
907 } else {
908 nfc->disable_verification_requirement(_type);
909 }
910 }
911
912 virtual void on_disable_verification_requirement(M24srDriver *nfc, M24srError_t status, PasswordType_t)
913 {
914 on_finish_command(nfc, status);
915 }
916
917 virtual void on_change_reference_data(M24srDriver *nfc, M24srError_t status, PasswordType_t type, const uint8_t *)
918 {
919 if (status == M24SR_SUCCESS) {
920 nfc->enable_permanent_state(type);
921 } else {
922 on_finish_command(nfc, status);
923 }
924 }
925
926 virtual void on_enable_permanent_state(M24srDriver *nfc, M24srError_t status, PasswordType_t)
927 {
928 on_finish_command(nfc, status);
929 }
930
931 private:
932 /**
933 * Remove the private callbacks and call the user callback.
934 * @param nfc Object triggering the command.
935 * @param status Command status.
936 */
937 void on_finish_command(M24srDriver *nfc, M24srError_t status)
938 {
939 nfc->_subcommand_cb = NULL;
940
941 if (_enable) {
942 if (_type == READ_PASSWORD) {
943 nfc->get_callback()->on_enable_read_password(nfc, status, _new_password);
944 } else {
945 nfc->get_callback()->on_enable_write_password(nfc, status, _new_password);
946 }
947 } else {
948 if (_type == READ_PASSWORD) {
949 nfc->get_callback()->on_disable_read_password(nfc, status);
950 } else {
951 nfc->get_callback()->on_disable_write_password(nfc, status);
952 }
953 }
954 }
955
956 private:
957 const uint8_t *_new_password;
958 PasswordType_t _type;
959 bool _enable;
960 };
961
962 /**
963 * @brief This class permits to disable all the password requests to read/write into the tag.
964 */
965 class RemoveAllPasswordCallback : public Callbacks {
966 public:
967 /**
968 * Build the chain of callbacks.
969 */
970 RemoveAllPasswordCallback()
971 : _password(NULL) { }
972
973 /* This class is equivalent to calling the methods:
974 * - verify(i2c)
975 * - disable_permanent_state(Read)
976 * - disable_permanent_state(write)
977 * - disable_verification_requirement(Read)
978 * - disable_verification_requirement(write)
979 * - change_reference_data(Read)
980 * - change_reference_data(write)
981 */
982
983 virtual void on_verified(M24srDriver *nfc, M24srError_t status, PasswordType_t, const uint8_t *data)
984 {
985 if (status != M24SR_SUCCESS) {
986 return on_finish_command(nfc, status);
987 }
988 _password = data;
989 nfc->disable_permanent_state(READ_PASSWORD);
990 }
991
992 virtual void on_disable_permanent_state(M24srDriver *nfc, M24srError_t status, PasswordType_t type)
993 {
994 if (status != M24SR_SUCCESS) {
995 return on_finish_command(nfc, status);
996 }
997 if (type == READ_PASSWORD) {
998 nfc->disable_permanent_state(WRITE_PASSWORD);
999 } else {
1000 nfc->disable_verification_requirement(READ_PASSWORD);
1001 }
1002 }
1003
1004 virtual void on_disable_verification_requirement(M24srDriver *nfc, M24srError_t status, PasswordType_t type)
1005 {
1006 if (status != M24SR_SUCCESS) {
1007 return on_finish_command(nfc, status);
1008 }
1009 if (type == READ_PASSWORD) {
1010 nfc->disable_verification_requirement(WRITE_PASSWORD);
1011 } else {
1012 nfc->change_reference_data(READ_PASSWORD, _password);
1013 }
1014 }
1015
1016 virtual void on_change_reference_data(M24srDriver *nfc, M24srError_t status, PasswordType_t type,
1017 const uint8_t *data)
1018 {
1019 if (status != M24SR_SUCCESS) {
1020 return on_finish_command(nfc, status);
1021 }
1022 if (type == READ_PASSWORD) {
1023 nfc->change_reference_data(WRITE_PASSWORD, data);
1024 } else {
1025 on_finish_command(nfc, status);
1026 }
1027 }
1028
1029 private:
1030 /**
1031 * Remove the private callback and call the onDisableAllPassword callback.
1032 * @param nfc Object triggering the command.
1033 * @param status Command status.
1034 */
1035 void on_finish_command(M24srDriver *nfc, M24srError_t status)
1036 {
1037 nfc->_subcommand_cb = NULL;
1038 _password = NULL;
1039 nfc->get_callback()->on_disable_all_password(nfc, status);
1040 }
1041
1042 private:
1043 /**
1044 * Store the default password used for open a super user session
1045 * it will be set as default read/write password
1046 */
1047 const uint8_t *_password;
1048 };
1049
1050 /**
1051 * @brief This class permits to set the tag as read/write only.
1052 */
1053 class ChangeAccessStateCallback : public Callbacks {
1054 public:
1055 enum AccessType_t {
1056 WRITE,
1057 READ
1058 };
1059
1060 /**
1061 * Build the chain of callbacks.
1062 */
1063 ChangeAccessStateCallback()
1064 : _type(WRITE),
1065 _enable(false) { }
1066
1067 /* This class is equivalent to calling the methods:
1068 * - verify(i2c)
1069 * - enable_permanent_state(Read/write)
1070 * or:
1071 * - verify(i2c)
1072 * - disable_permanent_state</li>
1073 * - disable_verification_requirement(Read/write)
1074 */
1075
1076 /**
1077 * Set the access to enable/disable an access type.
1078 * @param type Access type.
1079 * @param enable True to enable the state, False to disable it.
1080 */
1081 void change_access_state(AccessType_t type, bool enable)
1082 {
1083 _type = type;
1084 _enable = enable;
1085 }
1086
1087 virtual void on_verified(M24srDriver *nfc, M24srError_t status, PasswordType_t, const uint8_t *)
1088 {
1089 if (status != M24SR_SUCCESS) {
1090 return on_finish_command(nfc, status);
1091 }
1092
1093 if (_enable) {
1094 nfc->disable_permanent_state(_type == WRITE ? WRITE_PASSWORD : READ_PASSWORD);
1095 } else {
1096 nfc->enable_permanent_state(_type == WRITE ? WRITE_PASSWORD : READ_PASSWORD);
1097 }
1098
1099 }
1100
1101 virtual void on_disable_permanent_state(M24srDriver *nfc, M24srError_t status, PasswordType_t type)
1102 {
1103 if (status != M24SR_SUCCESS) {
1104 return on_finish_command(nfc, status);
1105 }
1106
1107 nfc->disable_verification_requirement(type);
1108 }
1109
1110 virtual void on_disable_verification_requirement(M24srDriver *nfc, M24srError_t status, PasswordType_t)
1111 {
1112 on_finish_command(nfc, status);
1113 }
1114
1115 virtual void on_enable_permanent_state(M24srDriver *nfc, M24srError_t status, PasswordType_t)
1116 {
1117 on_finish_command(nfc, status);
1118 }
1119
1120 private:
1121 /**
1122 * Remove the private callback and call the user callback.
1123 * @param nfc Object triggering the command.
1124 * @param status Command status.
1125 */
1126 void on_finish_command(M24srDriver *nfc, M24srError_t status)
1127 {
1128 nfc->_subcommand_cb = NULL;
1129 if (_enable) {
1130 if (_type == READ) {
1131 //enable read = disable write only
1132 nfc->get_callback()->on_disable_write_only(nfc, status);
1133 } else {
1134 //enable write = disable read only
1135 nfc->get_callback()->on_disable_read_only(nfc, status);
1136 }
1137 } else {
1138 if (_type == WRITE) {
1139 //disable write = enable read only
1140 nfc->get_callback()->on_enable_read_only(nfc, status);
1141 } else {
1142 nfc->get_callback()->on_enable_write_only(nfc, status);
1143 }
1144 }
1145 }
1146
1147 private:
1148 AccessType_t _type;
1149 bool _enable;
1150 };
1151
1152 /**
1153 * @brief Object with the callback used to send a ManageGPO command.
1154 */
1155 class ManageGPOCallback : public Callbacks {
1156
1157 public:
1158 /**
1159 * Build the chain of callbacks.
1160 * @param parent Parent component to run the command on.
1161 */
1162 ManageGPOCallback()
1163 : _new_gpo_config(HIGH_IMPEDANCE),
1164 _read_gpo_config(0),
1165 _change_i2c_gpo(true) { }
1166
1167 /* This class is equivalent to calling the methods:
1168 * - selected_application
1169 * - select_system_file
1170 * - read_binary
1171 * - verify
1172 * - update_binary
1173 */
1174
1175 /**
1176 * Command parameters.
1177 * @param i2cGpo true to change the i2c gpo, false for the rf gpo.
1178 * @param new_config new gpo function.
1179 */
1180 void set_new_gpo_config(bool i2cGpo, NfcGpoState_t new_config)
1181 {
1182 _new_gpo_config = new_config;
1183 _change_i2c_gpo = i2cGpo;
1184 }
1185
1186 virtual void on_selected_application(M24srDriver *nfc, M24srError_t status)
1187 {
1188 if (status == M24SR_SUCCESS) {
1189 nfc->select_system_file();
1190 } else {
1191 on_finish_command(nfc, status);
1192 }
1193 }
1194
1195 virtual void on_selected_system_file(M24srDriver *nfc, M24srError_t status)
1196 {
1197 if (status == M24SR_SUCCESS) {
1198 nfc->read_binary(0x0004, 0x01, &_read_gpo_config);
1199 } else {
1200 on_finish_command(nfc, status);
1201 }
1202 }
1203
1204 virtual void on_read_byte(M24srDriver *nfc, M24srError_t status, uint16_t, uint8_t *, uint16_t)
1205 {
1206 if (status == M24SR_SUCCESS) {
1207 nfc->verify(I2C_PASSWORD, default_password);
1208 } else {
1209 on_finish_command(nfc, status);
1210 }
1211 }
1212
1213 virtual void on_verified(M24srDriver *nfc, M24srError_t status, PasswordType_t, const uint8_t *)
1214 {
1215 if (status != M24SR_SUCCESS) {
1216 return on_finish_command(nfc, status);
1217 }
1218
1219 if (_change_i2c_gpo) {
1220 _read_gpo_config = (_read_gpo_config & 0xF0) | (uint8_t) _new_gpo_config;
1221 } else {
1222 _read_gpo_config = (_read_gpo_config & 0x0F) | (((uint8_t) _new_gpo_config) << 4);
1223 }
1224
1225 nfc->update_binary(0x0004, 0x01, &_read_gpo_config);
1226 }
1227
1228 virtual void on_updated_binary(M24srDriver *nfc, M24srError_t status, uint16_t, uint8_t *, uint16_t)
1229 {
1230
1231 if (status == M24SR_SUCCESS) {
1232 if (_new_gpo_config == I2C_ANSWER_READY) {
1233 nfc->_communication_type = ASYNC;
1234 } else {
1235 nfc->_communication_type = SYNC;
1236 }
1237 }
1238 on_finish_command(nfc, status);
1239 }
1240
1241 private:
1242 /**
1243 * Remove the private callback and call the user callback.
1244 * @param nfc Object where the command was send to.
1245 * @param status Command status.
1246 */
1247 void on_finish_command(M24srDriver *nfc, M24srError_t status)
1248 {
1249 nfc->_subcommand_cb = NULL;
1250 if (_change_i2c_gpo) {
1251 nfc->_command_cb->on_manage_i2c_gpo(nfc, status, _new_gpo_config);
1252 } else {
1253 nfc->_command_cb->on_manage_rf_gpo(nfc, status, _new_gpo_config);
1254 }
1255 }
1256
1257 private:
1258 /** new gpo function that this class has to write */
1259 NfcGpoState_t _new_gpo_config;
1260
1261 /** variable where storeing the read gpo configuration */
1262 uint8_t _read_gpo_config;
1263
1264 /** true to change the i2c gpo, false to change the rf gpo */
1265 bool _change_i2c_gpo;
1266 };
1267
1268 /**
1269 * @brief Object with the callback used to read the component ID
1270 */
1271 class ReadIDCallback : public Callbacks {
1272 public:
1273 /**
1274 * Build the chain of callbacks.
1275 * @param parent object where to send the command to.
1276 */
1277 ReadIDCallback() : _id(NULL) { }
1278
1279 /* This class is equivalent to calling the methods:
1280 * - select_application
1281 * - select_system_file
1282 * - read_binary
1283 */
1284
1285 /**
1286 * Set the variable containing the result
1287 * @param idPtr
1288 */
1289 void set_task(uint8_t *id)
1290 {
1291 _id = id;
1292 }
1293
1294 virtual void on_selected_application(M24srDriver *nfc, M24srError_t status)
1295 {
1296 if (status == M24SR_SUCCESS) {
1297 nfc->select_system_file();
1298 } else {
1299 on_finish_command(nfc, status);
1300 }
1301
1302 }
1303
1304 virtual void on_selected_system_file(M24srDriver *nfc, M24srError_t status)
1305 {
1306 if (status == M24SR_SUCCESS) {
1307 nfc->read_binary(0x0011, 0x01, _id);
1308 } else {
1309 on_finish_command(nfc, status);
1310 }
1311 }
1312
1313 virtual void on_read_byte(M24srDriver *nfc, M24srError_t status, uint16_t, uint8_t *, uint16_t)
1314 {
1315 on_finish_command(nfc, status);
1316 }
1317
1318 private:
1319 /**
1320 * Remove the private callback and call the user onReadId function.
1321 * @param nfc Object where the command was send.
1322 * @param status Command status.
1323 */
1324 void on_finish_command(M24srDriver *nfc, M24srError_t status)
1325 {
1326 nfc->_subcommand_cb = NULL;
1327 nfc->get_callback()->on_read_id(nfc, status, _id);
1328 }
1329
1330 private:
1331 /** pointer to read id */
1332 uint8_t *_id;
1333 };
1334
1335 /**
1336 * Class containing the callback needed to open a session and read the max
1337 * read/write size
1338 */
1339 class OpenSessionCallBack : public Callbacks {
1340 public:
1341 OpenSessionCallBack()
1342 : _retries(OPEN_SESSION_RETRIES) { }
1343
1344 void on_session_open(M24srDriver *nfc, M24srError_t status)
1345 {
1346 if (status == M24SR_SUCCESS) {
1347 nfc->select_application();
1348 } else {
1349 nfc->delegate()->on_session_started(false);
1350 }
1351 }
1352
1353 void on_selected_application(M24srDriver *nfc, M24srError_t status)
1354 {
1355 if (status == M24SR_SUCCESS) {
1356 nfc->select_cc_file();
1357 } else {
1358 if (_retries == 0) {
1359 nfc->delegate()->on_session_started(false);
1360 } else {
1361 _retries--;
1362 nfc->select_application();
1363 }
1364 }
1365 }
1366
1367 void on_selected_cc_file(M24srDriver *nfc, M24srError_t status)
1368 {
1369 if (status == M24SR_SUCCESS) {
1370 nfc->read_binary(0x0000, CC_FILE_LENGTH, CCFile);
1371 } else {
1372 nfc->delegate()->on_session_started(false);
1373 }
1374 }
1375
1376 void on_read_byte(M24srDriver *nfc, M24srError_t status, uint16_t, uint8_t *bytes_read,
1377 uint16_t read_count)
1378 {
1379 if (status != M24SR_SUCCESS || read_count != CC_FILE_LENGTH) {
1380 nfc->delegate()->on_session_started(false);
1381 }
1382 uint16_t ndef_file_id = (uint16_t)((bytes_read[0x09] << 8) | bytes_read[0x0A]);
1383 nfc->_max_read_bytes = (uint16_t)((bytes_read[0x03] << 8) | bytes_read[0x04]);
1384 nfc->_max_write_bytes = (uint16_t)((bytes_read[0x05] << 8) | bytes_read[0x06]);
1385 nfc->select_ndef_file(ndef_file_id);
1386 }
1387
1388 void on_selected_ndef_file(M24srDriver *nfc, M24srError_t status)
1389 {
1390 nfc->_is_session_open = (status == M24SR_SUCCESS);
1391 nfc->delegate()->on_session_started(nfc->_is_session_open);
1392 }
1393
1394 private:
1395 /** number of trials done for open the session */
1396 uint32_t _retries;
1397
1398 /** buffer where read the CC file */
1399 uint8_t CCFile[15];
1400 };
1401
1402 /**
1403 * Class containing the callback needed to close a session
1404 */
1405 class CloseSessionCallBack : public Callbacks {
1406 public:
1407 CloseSessionCallBack() { }
1408
1409 virtual void on_deselect(M24srDriver *nfc, M24srError_t status)
1410 {
1411 if (status == M24SR_SUCCESS) {
1412 nfc->_is_session_open = false;
1413 nfc->delegate()->on_session_ended(true);
1414 } else {
1415 nfc->delegate()->on_session_ended(false);
1416 }
1417 }
1418 };
1419
1420 /**
1421 * Class containing the callback needed to write a buffer
1422 */
1423 class WriteByteCallback : public Callbacks {
1424 public:
1425 WriteByteCallback() { }
1426
1427 virtual void on_updated_binary(M24srDriver *nfc, M24srError_t status, uint16_t offset, uint8_t *bytes_written,
1428 uint16_t write_count)
1429 {
1430 if (status != M24SR_SUCCESS) {
1431 nfc->delegate()->on_bytes_written(0);
1432 return;
1433 }
1434
1435 nfc->delegate()->on_bytes_written(write_count);
1436 }
1437 };
1438
1439 /**
1440 * Class containing the callback needed to read a buffer
1441 */
1442 class ReadByteCallback : public Callbacks {
1443 public:
1444 ReadByteCallback() { }
1445
1446 virtual void on_read_byte(M24srDriver *nfc, M24srError_t status, uint16_t offset, uint8_t *bytes_read,
1447 uint16_t read_count)
1448 {
1449 if (status != M24SR_SUCCESS) {
1450 nfc->delegate()->on_bytes_read(0);
1451 return;
1452 }
1453
1454 nfc->delegate()->on_bytes_read(read_count);
1455 }
1456 };
1457
1458 class SetSizeCallback : public Callbacks {
1459 public:
1460 SetSizeCallback() { }
1461
1462 virtual void on_updated_binary(M24srDriver *nfc, M24srError_t status, uint16_t offset, uint8_t *bytes_written,
1463 uint16_t write_count)
1464 {
1465 if (status != M24SR_SUCCESS) {
1466 nfc->delegate()->on_size_written(false);
1467 return;
1468 }
1469
1470 nfc->delegate()->on_size_written(true);
1471 }
1472 };
1473
1474 class GetSizeCallback : public Callbacks {
1475 public:
1476 GetSizeCallback() { }
1477
1478 virtual void on_read_byte(M24srDriver *nfc, M24srError_t status, uint16_t offset, uint8_t *bytes_read,
1479 uint16_t read_count)
1480 {
1481 if (status != M24SR_SUCCESS) {
1482 nfc->delegate()->on_size_read(false, 0);
1483 return;
1484 }
1485
1486 /* NDEF file size is BE */
1487 nfc->_ndef_size = (((uint16_t) nfc->_ndef_size_buffer[0]) << 8 | nfc->_ndef_size_buffer[1]);
1488
1489 nfc->delegate()->on_size_read(true, nfc->_ndef_size);
1490 }
1491 };
1492
1493 class EraseBytesCallback : public Callbacks {
1494 public:
1495 EraseBytesCallback() { }
1496
1497 virtual void on_updated_binary(M24srDriver *nfc, M24srError_t status, uint16_t offset, uint8_t *bytes_written,
1498 uint16_t write_count)
1499 {
1500 if (status != M24SR_SUCCESS) {
1501 nfc->delegate()->on_bytes_erased(0);
1502 return;
1503 }
1504
1505 nfc->delegate()->on_bytes_erased(write_count);
1506 }
1507 };
1508
1509private:
1510 /** Default password used to change the write/read permission */
1511 static const uint8_t default_password[16];
1512
1513 I2C _i2c_channel;
1514
1515 /** Interrupt object fired when the gpo status changes */
1516 InterruptIn _gpo_event_interrupt;
1517 DigitalIn _gpo_pin;
1518 DigitalOut _rf_disable_pin;
1519
1520 /** object containing the callbacks to use*/
1521 Callbacks *_command_cb;
1522
1523 /**
1524 * Object with private callbacks used to hide high level commands each
1525 * calling multiple low level commands. This callbacks object has
1526 * higher priority comparing to the user callbacks.
1527 */
1528 Callbacks *_subcommand_cb;
1529
1530 Callbacks _default_cb;
1531 ManageGPOCallback _manage_gpo_cb;
1532 ReadIDCallback _read_id_cb;
1533 ChangePasswordRequestStatusCallback _change_password_request_status_cb;
1534 RemoveAllPasswordCallback _remove_password_cb;
1535 ChangeAccessStateCallback _change_access_state_cb;
1536 OpenSessionCallBack _open_session_cb;
1537 CloseSessionCallBack _close_session_cb;
1538 WriteByteCallback _write_byte_cb;
1539 ReadByteCallback _read_byte_cb;
1540 SetSizeCallback _set_size_cb;
1541 GetSizeCallback _get_size_cb;
1542 EraseBytesCallback _erase_bytes_cb;
1543
1544
1545 uint8_t _buffer[0xFF];
1546
1547 /** Type of communication being used (SYNC, ASYNC) */
1548 Communication_t _communication_type;
1549
1550 Command_t _last_command;
1551 CommandData_t _last_command_data;
1552
1553 /** Buffer used to build the command to send to the chip. */
1554 uint16_t _ndef_size;
1555 uint8_t _ndef_size_buffer[NDEF_FILE_HEADER_SIZE];
1556 uint8_t _max_read_bytes;
1557 uint8_t _max_write_bytes;
1558 uint8_t _did_byte;
1559
1560 bool _is_session_open;
1561};
1562
1563} //ST
1564} //vendor
1565} //nfc
1566} //mbed
1567
1568#endif // M24SR_H
1569
1570/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
int call(F f, Args ...args)
Calls an event on the queue.
A digital input, used for reading the state of a pin.
Definition: DigitalIn.h:60
A digital output, used for setting the state of a pin.
Definition: DigitalOut.h:55
An I2C Master, used for communicating with I2C slave devices.
Definition: I2C.h:211
A digital interrupt input, used to call a function on a rising or falling edge.
Definition: InterruptIn.h:65
The abstraction for a NFC EEPROM driver.
APDU Command structure.
Definition: m24sr_driver.h:98
Object that contains all the callbacks fired by this class, each command has its own callback.
Definition: m24sr_driver.h:235
virtual void on_change_reference_data(M24srDriver *nfc, M24srError_t status, PasswordType_t type, const uint8_t *data)
called when change_reference_data completes
Definition: m24sr_driver.h:327
virtual void on_selected_application(M24srDriver *nfc, M24srError_t status)
called when select_application completes
Definition: m24sr_driver.h:252
virtual void on_enable_permanent_state(M24srDriver *nfc, M24srError_t status, PasswordType_t type)
called when enable_permanent_state completes
Definition: m24sr_driver.h:353
virtual void on_disable_verification_requirement(M24srDriver *nfc, M24srError_t status, PasswordType_t type)
called when disable_verification_requirement completes
Definition: m24sr_driver.h:345
virtual void on_deselect(M24srDriver *nfc, M24srError_t status)
called when deselect completes
Definition: m24sr_driver.h:245
virtual void on_updated_binary(M24srDriver *nfc, M24srError_t status, uint16_t offset, uint8_t *bytes_written, uint16_t write_count)
called when update_binary completes
Definition: m24sr_driver.h:291
virtual void on_selected_cc_file(M24srDriver *nfc, M24srError_t status)
called when select_cc_file completes
Definition: m24sr_driver.h:259
virtual void on_selected_ndef_file(M24srDriver *nfc, M24srError_t status)
called when select_ndef_file completes
Definition: m24sr_driver.h:266
virtual void on_read_id(M24srDriver *nfc, M24srError_t status, uint8_t *id)
called when read_id completes
Definition: m24sr_driver.h:369
virtual void on_disable_read_only(M24srDriver *nfc, M24srError_t status)
called when disable_read_only completes
Definition: m24sr_driver.h:428
virtual void on_manage_i2c_gpo(M24srDriver *nfc, M24srError_t status, NfcGpoState_t new_status)
called when manage_i2c_gpo completes
Definition: m24sr_driver.h:311
virtual void on_enable_write_password(M24srDriver *nfc, M24srError_t status, const uint8_t *new_password)
called when oenable_write_password completes
Definition: m24sr_driver.h:385
virtual void on_session_open(M24srDriver *nfc, M24srError_t status)
called when get_session completes
Definition: m24sr_driver.h:238
virtual void on_disable_all_password(M24srDriver *nfc, M24srError_t status)
called when disable_all_password completes
Definition: m24sr_driver.h:407
virtual void on_manage_rf_gpo(M24srDriver *nfc, M24srError_t status, NfcGpoState_t new_status)
called when manage_rf_gpo completes
Definition: m24sr_driver.h:319
virtual void on_disable_write_password(M24srDriver *nfc, M24srError_t status)
called when disable_write_password completes
Definition: m24sr_driver.h:400
virtual void on_enable_read_password(M24srDriver *nfc, M24srError_t status, const uint8_t *new_password)
called when enable_read_password completes
Definition: m24sr_driver.h:377
virtual void on_disable_permanent_state(M24srDriver *nfc, M24srError_t status, PasswordType_t type)
called when disable_permanent_state completes
Definition: m24sr_driver.h:361
virtual void on_enable_read_only(M24srDriver *nfc, M24srError_t status)
called when enable_read_only completes
Definition: m24sr_driver.h:414
virtual void on_disable_read_password(M24srDriver *nfc, M24srError_t status)
called when disable_read_password completes
Definition: m24sr_driver.h:393
virtual void on_read_byte(M24srDriver *nfc, M24srError_t status, uint16_t offset, uint8_t *bytes_read, uint16_t read_count)
called when read_binary completes
Definition: m24sr_driver.h:280
virtual void on_enable_write_only(M24srDriver *nfc, M24srError_t status)
called when enable_write_only completes
Definition: m24sr_driver.h:421
virtual void on_selected_system_file(M24srDriver *nfc, M24srError_t status)
called when select_system_file completes
Definition: m24sr_driver.h:273
virtual void on_verified(M24srDriver *nfc, M24srError_t status, PasswordType_t password_type, const uint8_t *pwd)
called when verify completes
Definition: m24sr_driver.h:302
virtual void on_disable_write_only(M24srDriver *nfc, M24srError_t status)
called when disable_write_only completes
Definition: m24sr_driver.h:435
virtual void on_enable_verification_requirement(M24srDriver *nfc, M24srError_t status, PasswordType_t type)
called when enable_verification_requirement completes
Definition: m24sr_driver.h:337
Class representing a M24SR component.
Definition: m24sr_driver.h:229
virtual void start_session(bool force=true)
Definition: m24sr_driver.h:474
virtual void write_bytes(uint32_t address, const uint8_t *bytes, size_t count)
Definition: m24sr_driver.h:531
virtual void write_size(size_t count)
Definition: m24sr_driver.h:570
virtual void read_bytes(uint32_t address, uint8_t *bytes, size_t count)
Definition: m24sr_driver.h:496
M24srDriver(PinName i2c_data_pin=NC, PinName i2c_clock_pin=NC, PinName gpo_pin=NC, PinName rf_disable_pin=NC)
Create the driver, default pin names will be used appropriate for the board.
virtual void erase_bytes(uint32_t address, size_t size)
Definition: m24sr_driver.h:610
Callback< R(ArgTs...)> callback(R(*func)(ArgTs...)=nullptr) noexcept
Create a callback class with type inferred from the arguments.
Definition: Callback.h:678
virtual void on_size_read(bool success, size_t size)=0
Completion of size retrieval operation.
virtual void on_bytes_written(size_t count)=0
Completion of write operation.
virtual void on_session_started(bool success)=0
Completion of session start operation.
virtual void on_bytes_read(size_t count)=0
Completion of read operation.
const uint8_t * data
Command parameters.
Definition: m24sr_driver.h:109
uint8_t LE
Expected length of data to be returned.
Definition: m24sr_driver.h:110
User parameter used to invoke a command, it is used to provide the data back with the response.
Definition: m24sr_driver.h:89
uint16_t length
number of bytes in the data array
Definition: m24sr_driver.h:91
uint16_t offset
offset parameter used in the read/write command
Definition: m24sr_driver.h:92
SC response structure.
Definition: m24sr_driver.h:131
uint8_t SW1
Command Processing status.
Definition: m24sr_driver.h:133
uint8_t * data
Data returned from the card.
Definition: m24sr_driver.h:132
uint8_t SW2
Command Processing qualification.
Definition: m24sr_driver.h:134