takashi kadono / Mbed OS Nucleo_446

Dependencies:   ssd1331

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /*
00002  * Copyright (c) 2017, ARM Limited, All Rights Reserved
00003  * SPDX-License-Identifier: Apache-2.0
00004  *
00005  * Licensed under the Apache License, Version 2.0 (the "License"); you may
00006  * not use this file except in compliance with the License.
00007  * You may obtain a copy of the License at
00008  *
00009  * http://www.apache.org/licenses/LICENSE-2.0
00010  *
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
00013  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  */
00017 
00018 #include "mbed.h"
00019 #include "greentea-client/test_env.h"
00020 #include "unity.h"
00021 #include "utest.h"
00022 
00023 #include <events/mbed_events.h>
00024 #include "NFCEEPROMDriver.h"
00025 
00026 #if !MBED_CONF_NFCEEPROM
00027 #error [NOT_SUPPORTED] NFC EEPROM not supported for this target
00028 #endif
00029 
00030 using namespace utest::v1;
00031 using namespace mbed::nfc;
00032 
00033 /* individual steps that map to specific operations that include parameters */
00034 typedef enum {
00035     START_SESSION        = 0x0000,
00036 
00037     END_SESSION          = 0x0100,
00038 
00039     READ_BYTES           = 0x0200,
00040     READ_2_BYTES         = 0x0201,
00041     READ_2_BYTES_OFFSET_FAIL = 0x0202,
00042     READ_4_BYTES         = 0x0203,
00043     READ_4_BYTES_MIXED   = 0x0204,
00044     READ_4_BYTES_OFFSET  = 0x0205,
00045     READ_4_BYTES_ERASED  = 0x0206,
00046     READ_4_BYTES_FAIL    = 0x0207,
00047 
00048     WRITE_BYTES          = 0x0300,
00049     WRITE_2_BYTES        = 0x0301,
00050     WRITE_2_BYTES_OFFSET = 0x0302,
00051     WRITE_2_BYTES_OFFSET_FAIL = 0x0303,
00052     WRITE_4_BYTES        = 0x0304,
00053     WRITE_4_BYTES_FAIL   = 0x0305,
00054 
00055     ERASE_BYTES          = 0x0400,
00056     ERASE_4_BYTES        = 0x0401,
00057 
00058     READ_SIZE            = 0x0500,
00059     READ_SIZE_2          = 0x0501,
00060     READ_SIZE_4          = 0x0502,
00061 
00062     WRITE_SIZE           = 0x0600,
00063     WRITE_SIZE_2         = 0x0601,
00064     WRITE_SIZE_4         = 0x0602,
00065 
00066     TERMINATE            = 0xFF00
00067 } TestCommand_t;
00068 
00069 /* We group the command based on their fist byte to simplify step checking.
00070  * Individual conditions of a step are checked in the event so this doesn't
00071  * sacrifice any correctness checking */
00072 const size_t TEST_COMMAND_GROUP_MASK = 0xFF00;
00073 
00074 /* test case sequences that index into the array of commands which comprise them */
00075 typedef enum {
00076     SESSION_TEST,
00077     WRITE_READ_TEST,
00078     ERASE_TEST,
00079     WRITE_READ_SIZE_TEST,
00080     TRUNCATE_TEST,
00081     WRITE_TRUNCATE_TEST,
00082     WRITE_WITH_OFFSET_TEST,
00083     WRITE_BEYOND_SIZE_TEST,
00084     SEQUENCE_MAX
00085 } TestSequence_t;
00086 
00087 static EventQueue event_queue(/* event count */ 10 * EVENTS_EVENT_SIZE);
00088 
00089 static const size_t MAX_STEP = 10;
00090 static const size_t BUFFER_MAX = 10;
00091 
00092 /* defines the "script" the test follows, each step is checked and all
00093  * have to execute to completion for a successful run */
00094 static const TestCommand_t SEQUENCES[SEQUENCE_MAX][MAX_STEP] = {
00095     /* SESSION_TEST */
00096     { START_SESSION, END_SESSION, TERMINATE },
00097 
00098     /* WRITE_READ_TEST */
00099     {
00100         START_SESSION, WRITE_SIZE_4, READ_SIZE_4, WRITE_4_BYTES, READ_4_BYTES,
00101         WRITE_2_BYTES, READ_4_BYTES_MIXED, END_SESSION, TERMINATE
00102     },
00103 
00104     /* ERASE_TEST */
00105     {
00106         START_SESSION, WRITE_SIZE_4, READ_SIZE_4, WRITE_4_BYTES, READ_4_BYTES,
00107         ERASE_4_BYTES, READ_4_BYTES_ERASED, END_SESSION, TERMINATE
00108     },
00109 
00110     /* WRITE_READ_SIZE_TEST */
00111     {
00112         START_SESSION, WRITE_SIZE_2, READ_SIZE_2, WRITE_SIZE_4, READ_SIZE_4,
00113         END_SESSION, TERMINATE
00114     },
00115 
00116     /* TRUNCATE_TEST */
00117     {
00118         START_SESSION, WRITE_SIZE_4, READ_SIZE_4, WRITE_4_BYTES, READ_4_BYTES,
00119         WRITE_SIZE_2, READ_SIZE_2, READ_4_BYTES_FAIL, END_SESSION, TERMINATE
00120     },
00121 
00122     /* WRITE_TRUNCATE_TEST */
00123     {
00124         START_SESSION, WRITE_SIZE_2, READ_SIZE_2, WRITE_4_BYTES_FAIL, READ_4_BYTES_FAIL,
00125         END_SESSION, TERMINATE
00126     },
00127 
00128     /* WRITE_WITH_OFFSET_TEST */
00129     {
00130         START_SESSION, WRITE_SIZE_4, READ_SIZE_4, WRITE_4_BYTES, READ_4_BYTES,
00131         WRITE_2_BYTES_OFFSET, READ_4_BYTES_OFFSET, END_SESSION, TERMINATE
00132     },
00133 
00134     /* WRITE_BEYOND_SIZE_TEST */
00135     {
00136         START_SESSION, WRITE_SIZE_2, READ_SIZE_2, WRITE_2_BYTES_OFFSET_FAIL, READ_2_BYTES_OFFSET_FAIL,
00137         WRITE_2_BYTES, READ_2_BYTES, END_SESSION, TERMINATE
00138     }
00139 };
00140 
00141 static const uint8_t DATA_4_BYTES[] = { 0x01, 0x02, 0x03, 0x04 };
00142 static const uint8_t DATA_2_BYTES[] = { 0x05, 0x06 };
00143 static const uint8_t DATA_4_BYTES_MIXED[] = { 0x05, 0x06, 0x03, 0x04 };
00144 static const uint8_t DATA_4_BYTES_OFFSET[] = { 0x01, 0x02, 0x05, 0x06 };
00145 static const uint8_t DATA_4_BYTES_ERASED[] = { 0x00, 0x00, 0x00, 0x00 };
00146 
00147 class DriverTest : public NFCEEPROMDriver::Delegate {
00148 public:
00149     DriverTest(NFCEEPROMDriver *_driver)
00150         : _operation_data(NULL),
00151           _driver(_driver),
00152           _sequence(SEQUENCE_MAX),
00153           _step(0),
00154           _result_size(0),
00155           _address(0),
00156           _success(true) { };
00157 
00158     virtual ~DriverTest() { };
00159 
00160     /* Delegate events */
00161 
00162     virtual void on_session_started(bool success)
00163     {
00164         if (success != _success) {
00165             TEST_FAIL_MESSAGE("failed to start session");
00166         }
00167 
00168         evaluate_step(START_SESSION);
00169     };
00170 
00171     virtual void on_session_ended(bool success)
00172     {
00173         if (success != _success) {
00174             TEST_FAIL_MESSAGE("failed to end session");
00175         }
00176 
00177         evaluate_step(END_SESSION);
00178     };
00179 
00180     virtual void on_bytes_read(size_t count)
00181     {
00182         if (count != _result_size) {
00183             TEST_FAIL_MESSAGE("failed to read bytes");
00184         }
00185         if (memcmp(_buffer, _operation_data, count) != 0) {
00186             TEST_FAIL_MESSAGE("read bytes are different than expected");
00187         }
00188 
00189         evaluate_step(READ_BYTES);
00190     };
00191 
00192     virtual void on_bytes_written(size_t count)
00193     {
00194         if (count != _result_size) {
00195             TEST_FAIL_MESSAGE("failed to write bytes");
00196         }
00197 
00198         evaluate_step(WRITE_BYTES);
00199     };
00200 
00201     virtual void on_size_written(bool success)
00202     {
00203         if (success != _success) {
00204             TEST_FAIL_MESSAGE("failed to write size");
00205         }
00206 
00207         evaluate_step(WRITE_SIZE);
00208     };
00209 
00210     virtual void on_size_read(bool success, size_t size)
00211     {
00212         if (success != _success || size != _result_size) {
00213             TEST_FAIL_MESSAGE("failed to read size");
00214         }
00215 
00216         evaluate_step(READ_SIZE);
00217     };
00218 
00219     virtual void on_bytes_erased(size_t count)
00220     {
00221         if (count != _result_size) {
00222             TEST_FAIL_MESSAGE("failed to erase bytes");
00223         }
00224 
00225         evaluate_step(ERASE_BYTES);
00226     }
00227 
00228     /* Sequence running code */
00229 
00230     void run_sequence(TestSequence_t sequence)
00231     {
00232         _sequence = sequence;
00233 
00234         if (_sequence >= SEQUENCE_MAX) {
00235             TEST_FAIL_MESSAGE("internal test failure - invalid command");
00236         }
00237 
00238         execute_next_step();
00239 
00240         event_queue.dispatch_forever();
00241 
00242         TEST_ASSERT_EQUAL(TERMINATE, SEQUENCES[_sequence][_step]);
00243     }
00244 
00245     void execute_next_step()
00246     {
00247         TestCommand_t command = SEQUENCES[_sequence][_step];
00248 
00249         /* setup data buffer */
00250         switch (command) {
00251             case READ_2_BYTES:
00252             case READ_2_BYTES_OFFSET_FAIL:
00253             case WRITE_2_BYTES:
00254             case WRITE_2_BYTES_OFFSET:
00255             case WRITE_2_BYTES_OFFSET_FAIL:
00256                 _operation_data = DATA_2_BYTES;
00257                 break;
00258             case READ_4_BYTES:
00259             case READ_4_BYTES_FAIL:
00260             case WRITE_4_BYTES:
00261             case WRITE_4_BYTES_FAIL:
00262                 _operation_data = DATA_4_BYTES;
00263                 break;
00264             case READ_4_BYTES_ERASED:
00265                 _operation_data = DATA_4_BYTES_ERASED;
00266                 break;
00267             case READ_4_BYTES_MIXED:
00268                 _operation_data = DATA_4_BYTES_MIXED;
00269                 break;
00270             case READ_4_BYTES_OFFSET:
00271                 _operation_data = DATA_4_BYTES_OFFSET;
00272                 break;
00273             default:
00274                 _operation_data = NULL;
00275         }
00276 
00277         /* setup result size */
00278         switch (command) {
00279             case READ_2_BYTES:
00280             case READ_4_BYTES_FAIL:
00281             case WRITE_2_BYTES:
00282             case WRITE_4_BYTES_FAIL:
00283             case WRITE_2_BYTES_OFFSET:
00284             case READ_SIZE_2:
00285                 _result_size = 2;
00286                 break;
00287             case READ_4_BYTES:
00288             case READ_4_BYTES_ERASED:
00289             case READ_4_BYTES_MIXED:
00290             case READ_4_BYTES_OFFSET:
00291             case WRITE_4_BYTES:
00292             case ERASE_4_BYTES:
00293             case READ_SIZE_4:
00294                 _result_size = 4;
00295                 break;
00296             default:
00297                 _result_size = 0;
00298         }
00299 
00300         /* setup operation size */
00301         switch (command) {
00302             case READ_2_BYTES:
00303             case READ_2_BYTES_OFFSET_FAIL:
00304             case WRITE_2_BYTES:
00305             case WRITE_2_BYTES_OFFSET:
00306             case WRITE_2_BYTES_OFFSET_FAIL:
00307             case WRITE_SIZE_2:
00308                 _operation_size = 2;
00309                 break;
00310             case READ_4_BYTES:
00311             case READ_4_BYTES_ERASED:
00312             case READ_4_BYTES_MIXED:
00313             case READ_4_BYTES_OFFSET:
00314             case READ_4_BYTES_FAIL:
00315             case WRITE_4_BYTES:
00316             case WRITE_4_BYTES_FAIL:
00317             case ERASE_4_BYTES:
00318             case READ_SIZE_4:
00319             case WRITE_SIZE_4:
00320                 _operation_size = 4;
00321                 break;
00322             default:
00323                 _operation_size = 0;
00324         }
00325 
00326         /* setup offset */
00327         switch (command) {
00328             case READ_2_BYTES_OFFSET_FAIL:
00329             case WRITE_2_BYTES_OFFSET:
00330             case WRITE_2_BYTES_OFFSET_FAIL:
00331                 _address = 2;
00332                 break;
00333             default:
00334                 _address = 0;
00335         }
00336 
00337         /* setup command success */
00338         switch (command) {
00339             case READ_2_BYTES_OFFSET_FAIL:
00340             case WRITE_2_BYTES_OFFSET_FAIL:
00341                 _success = false;
00342                 break;
00343             default:
00344                 _success = true;
00345         }
00346 
00347         /* call next command */
00348         switch (command & TEST_COMMAND_GROUP_MASK) {
00349             case START_SESSION:
00350                 _driver->start_session(true);
00351                 break;
00352             case END_SESSION:
00353                 _driver->end_session();
00354                 break;
00355             case READ_BYTES:
00356                 _driver->read_bytes(_address, _buffer, _operation_size);
00357                 break;
00358             case WRITE_BYTES:
00359                 _driver->write_bytes(_address, _operation_data, _operation_size);
00360                 break;
00361             case ERASE_BYTES:
00362                 _driver->erase_bytes(_address, 4);
00363                 break;
00364             case READ_SIZE:
00365                 _driver->read_size();
00366                 break;
00367             case WRITE_SIZE:
00368                 _driver->write_size(_operation_size);
00369                 break;
00370             case TERMINATE:
00371                 event_queue.break_dispatch();
00372                 break;
00373             default:
00374                 TEST_FAIL_MESSAGE("internal test failure - invalid command");
00375         }
00376     }
00377 
00378     void evaluate_step(TestCommand_t command_completed)
00379     {
00380         /* check last command succeeded */
00381         TEST_ASSERT_EQUAL(command_completed, SEQUENCES[_sequence][_step]&TEST_COMMAND_GROUP_MASK);
00382 
00383         _step++;
00384 
00385         if (_step == MAX_STEP) {
00386             TEST_FAIL_MESSAGE("internal test failure - too many steps");
00387         }
00388 
00389         execute_next_step();
00390     }
00391 
00392 private:
00393     uint8_t _buffer[BUFFER_MAX];
00394     const uint8_t *_operation_data;
00395 
00396     NFCEEPROMDriver *_driver;
00397 
00398     TestSequence_t _sequence;
00399     size_t _step;
00400     size_t _result_size;
00401     size_t _operation_size;
00402     size_t _address;
00403     bool _success;
00404 };
00405 
00406 /* test case running code */
00407 
00408 static DriverTest *driver_test;
00409 extern NFCEEPROMDriver *greentea_nfc_EEPROM_driver_get_instance();
00410 
00411 utest::v1::status_t test_setup(const Case *const source, const size_t index_of_case)
00412 {
00413     NFCEEPROMDriver *driver = greentea_nfc_EEPROM_driver_get_instance();
00414     driver_test = new DriverTest(driver);
00415 
00416     driver->set_event_queue(&event_queue);
00417     driver->set_delegate(driver_test);
00418     driver->reset();
00419 
00420     TEST_ASSERT_NOT_EQUAL(0, driver->read_max_size());
00421 
00422     return greentea_case_setup_handler(source, index_of_case);
00423 }
00424 
00425 void session()
00426 {
00427     driver_test->run_sequence(SESSION_TEST);
00428 }
00429 
00430 void write_read()
00431 {
00432     driver_test->run_sequence(WRITE_READ_TEST);
00433 }
00434 
00435 void erase_bytes()
00436 {
00437     driver_test->run_sequence(ERASE_TEST);
00438 }
00439 
00440 void write_read_size()
00441 {
00442     driver_test->run_sequence(WRITE_READ_SIZE_TEST);
00443 }
00444 
00445 void truncate_size()
00446 {
00447     driver_test->run_sequence(TRUNCATE_TEST);
00448 }
00449 
00450 void write_bytes_truncated()
00451 {
00452     driver_test->run_sequence(WRITE_TRUNCATE_TEST);
00453 }
00454 
00455 void write_with_offset()
00456 {
00457     driver_test->run_sequence(WRITE_WITH_OFFSET_TEST);
00458 }
00459 
00460 void write_beyond_size()
00461 {
00462     driver_test->run_sequence(WRITE_BEYOND_SIZE_TEST);
00463 }
00464 
00465 utest::v1::status_t test_tear_down(const Case *const source, const size_t passed,
00466                                    const size_t failed, const failure_t reason)
00467 {
00468     delete driver_test;
00469 
00470     return greentea_case_teardown_handler(source, passed, failed, reason);
00471 }
00472 
00473 /* test setup */
00474 
00475 utest::v1::status_t test_init(const size_t number_of_cases)
00476 {
00477     GREENTEA_SETUP(10, "default_auto");
00478     return greentea_test_setup_handler(number_of_cases);
00479 }
00480 
00481 // Test cases
00482 Case cases[] = {
00483     Case("NFCEEPROM-SESSION", test_setup, session, test_tear_down),
00484     Case("NFCEEPROM-WRITE-READ", test_setup, write_read, test_tear_down),
00485     Case("NFCEEPROM-ERASE-BYTES", test_setup, erase_bytes, test_tear_down),
00486     Case("NFCEEPROM-WRITE-READ-SIZE", test_setup, write_read_size, test_tear_down),
00487     Case("NFCEEPROM-TRUNCATE-SIZE", test_setup, truncate_size, test_tear_down),
00488     Case("NFCEEPROM-WRITE-BYTES-TRUNCATED", test_setup, write_bytes_truncated, test_tear_down),
00489     Case("NFCEEPROM-WRITE-WITH-OFFSET", test_setup, write_with_offset, test_tear_down),
00490     Case("NFCEEPROM-WRITE-BEYOND-SIZE", test_setup, write_beyond_size, test_tear_down)
00491 };
00492 
00493 Specification specification(test_init, cases);
00494 
00495 // Entry point into the tests
00496 int main()
00497 {
00498     return !Harness::run(specification);
00499 }