takashi kadono
/
Nucleo_446
Color Oled(SSD1331) connect to STMicroelectronics Nucleo-F466
Diff: mbed-os/TESTS/nfc/eeprom/main.cpp
- Revision:
- 0:8fdf9a60065b
diff -r 000000000000 -r 8fdf9a60065b mbed-os/TESTS/nfc/eeprom/main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os/TESTS/nfc/eeprom/main.cpp Wed Oct 10 00:33:53 2018 +0000 @@ -0,0 +1,499 @@ +/* + * Copyright (c) 2017, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mbed.h" +#include "greentea-client/test_env.h" +#include "unity.h" +#include "utest.h" + +#include <events/mbed_events.h> +#include "NFCEEPROMDriver.h" + +#if !MBED_CONF_NFCEEPROM +#error [NOT_SUPPORTED] NFC EEPROM not supported for this target +#endif + +using namespace utest::v1; +using namespace mbed::nfc; + +/* individual steps that map to specific operations that include parameters */ +typedef enum { + START_SESSION = 0x0000, + + END_SESSION = 0x0100, + + READ_BYTES = 0x0200, + READ_2_BYTES = 0x0201, + READ_2_BYTES_OFFSET_FAIL = 0x0202, + READ_4_BYTES = 0x0203, + READ_4_BYTES_MIXED = 0x0204, + READ_4_BYTES_OFFSET = 0x0205, + READ_4_BYTES_ERASED = 0x0206, + READ_4_BYTES_FAIL = 0x0207, + + WRITE_BYTES = 0x0300, + WRITE_2_BYTES = 0x0301, + WRITE_2_BYTES_OFFSET = 0x0302, + WRITE_2_BYTES_OFFSET_FAIL = 0x0303, + WRITE_4_BYTES = 0x0304, + WRITE_4_BYTES_FAIL = 0x0305, + + ERASE_BYTES = 0x0400, + ERASE_4_BYTES = 0x0401, + + READ_SIZE = 0x0500, + READ_SIZE_2 = 0x0501, + READ_SIZE_4 = 0x0502, + + WRITE_SIZE = 0x0600, + WRITE_SIZE_2 = 0x0601, + WRITE_SIZE_4 = 0x0602, + + TERMINATE = 0xFF00 +} TestCommand_t; + +/* We group the command based on their fist byte to simplify step checking. + * Individual conditions of a step are checked in the event so this doesn't + * sacrifice any correctness checking */ +const size_t TEST_COMMAND_GROUP_MASK = 0xFF00; + +/* test case sequences that index into the array of commands which comprise them */ +typedef enum { + SESSION_TEST, + WRITE_READ_TEST, + ERASE_TEST, + WRITE_READ_SIZE_TEST, + TRUNCATE_TEST, + WRITE_TRUNCATE_TEST, + WRITE_WITH_OFFSET_TEST, + WRITE_BEYOND_SIZE_TEST, + SEQUENCE_MAX +} TestSequence_t; + +static EventQueue event_queue(/* event count */ 10 * EVENTS_EVENT_SIZE); + +static const size_t MAX_STEP = 10; +static const size_t BUFFER_MAX = 10; + +/* defines the "script" the test follows, each step is checked and all + * have to execute to completion for a successful run */ +static const TestCommand_t SEQUENCES[SEQUENCE_MAX][MAX_STEP] = { + /* SESSION_TEST */ + { START_SESSION, END_SESSION, TERMINATE }, + + /* WRITE_READ_TEST */ + { + START_SESSION, WRITE_SIZE_4, READ_SIZE_4, WRITE_4_BYTES, READ_4_BYTES, + WRITE_2_BYTES, READ_4_BYTES_MIXED, END_SESSION, TERMINATE + }, + + /* ERASE_TEST */ + { + START_SESSION, WRITE_SIZE_4, READ_SIZE_4, WRITE_4_BYTES, READ_4_BYTES, + ERASE_4_BYTES, READ_4_BYTES_ERASED, END_SESSION, TERMINATE + }, + + /* WRITE_READ_SIZE_TEST */ + { + START_SESSION, WRITE_SIZE_2, READ_SIZE_2, WRITE_SIZE_4, READ_SIZE_4, + END_SESSION, TERMINATE + }, + + /* TRUNCATE_TEST */ + { + START_SESSION, WRITE_SIZE_4, READ_SIZE_4, WRITE_4_BYTES, READ_4_BYTES, + WRITE_SIZE_2, READ_SIZE_2, READ_4_BYTES_FAIL, END_SESSION, TERMINATE + }, + + /* WRITE_TRUNCATE_TEST */ + { + START_SESSION, WRITE_SIZE_2, READ_SIZE_2, WRITE_4_BYTES_FAIL, READ_4_BYTES_FAIL, + END_SESSION, TERMINATE + }, + + /* WRITE_WITH_OFFSET_TEST */ + { + START_SESSION, WRITE_SIZE_4, READ_SIZE_4, WRITE_4_BYTES, READ_4_BYTES, + WRITE_2_BYTES_OFFSET, READ_4_BYTES_OFFSET, END_SESSION, TERMINATE + }, + + /* WRITE_BEYOND_SIZE_TEST */ + { + START_SESSION, WRITE_SIZE_2, READ_SIZE_2, WRITE_2_BYTES_OFFSET_FAIL, READ_2_BYTES_OFFSET_FAIL, + WRITE_2_BYTES, READ_2_BYTES, END_SESSION, TERMINATE + } +}; + +static const uint8_t DATA_4_BYTES[] = { 0x01, 0x02, 0x03, 0x04 }; +static const uint8_t DATA_2_BYTES[] = { 0x05, 0x06 }; +static const uint8_t DATA_4_BYTES_MIXED[] = { 0x05, 0x06, 0x03, 0x04 }; +static const uint8_t DATA_4_BYTES_OFFSET[] = { 0x01, 0x02, 0x05, 0x06 }; +static const uint8_t DATA_4_BYTES_ERASED[] = { 0x00, 0x00, 0x00, 0x00 }; + +class DriverTest : public NFCEEPROMDriver::Delegate { +public: + DriverTest(NFCEEPROMDriver *_driver) + : _operation_data(NULL), + _driver(_driver), + _sequence(SEQUENCE_MAX), + _step(0), + _result_size(0), + _address(0), + _success(true) { }; + + virtual ~DriverTest() { }; + + /* Delegate events */ + + virtual void on_session_started(bool success) + { + if (success != _success) { + TEST_FAIL_MESSAGE("failed to start session"); + } + + evaluate_step(START_SESSION); + }; + + virtual void on_session_ended(bool success) + { + if (success != _success) { + TEST_FAIL_MESSAGE("failed to end session"); + } + + evaluate_step(END_SESSION); + }; + + virtual void on_bytes_read(size_t count) + { + if (count != _result_size) { + TEST_FAIL_MESSAGE("failed to read bytes"); + } + if (memcmp(_buffer, _operation_data, count) != 0) { + TEST_FAIL_MESSAGE("read bytes are different than expected"); + } + + evaluate_step(READ_BYTES); + }; + + virtual void on_bytes_written(size_t count) + { + if (count != _result_size) { + TEST_FAIL_MESSAGE("failed to write bytes"); + } + + evaluate_step(WRITE_BYTES); + }; + + virtual void on_size_written(bool success) + { + if (success != _success) { + TEST_FAIL_MESSAGE("failed to write size"); + } + + evaluate_step(WRITE_SIZE); + }; + + virtual void on_size_read(bool success, size_t size) + { + if (success != _success || size != _result_size) { + TEST_FAIL_MESSAGE("failed to read size"); + } + + evaluate_step(READ_SIZE); + }; + + virtual void on_bytes_erased(size_t count) + { + if (count != _result_size) { + TEST_FAIL_MESSAGE("failed to erase bytes"); + } + + evaluate_step(ERASE_BYTES); + } + + /* Sequence running code */ + + void run_sequence(TestSequence_t sequence) + { + _sequence = sequence; + + if (_sequence >= SEQUENCE_MAX) { + TEST_FAIL_MESSAGE("internal test failure - invalid command"); + } + + execute_next_step(); + + event_queue.dispatch_forever(); + + TEST_ASSERT_EQUAL(TERMINATE, SEQUENCES[_sequence][_step]); + } + + void execute_next_step() + { + TestCommand_t command = SEQUENCES[_sequence][_step]; + + /* setup data buffer */ + switch (command) { + case READ_2_BYTES: + case READ_2_BYTES_OFFSET_FAIL: + case WRITE_2_BYTES: + case WRITE_2_BYTES_OFFSET: + case WRITE_2_BYTES_OFFSET_FAIL: + _operation_data = DATA_2_BYTES; + break; + case READ_4_BYTES: + case READ_4_BYTES_FAIL: + case WRITE_4_BYTES: + case WRITE_4_BYTES_FAIL: + _operation_data = DATA_4_BYTES; + break; + case READ_4_BYTES_ERASED: + _operation_data = DATA_4_BYTES_ERASED; + break; + case READ_4_BYTES_MIXED: + _operation_data = DATA_4_BYTES_MIXED; + break; + case READ_4_BYTES_OFFSET: + _operation_data = DATA_4_BYTES_OFFSET; + break; + default: + _operation_data = NULL; + } + + /* setup result size */ + switch (command) { + case READ_2_BYTES: + case READ_4_BYTES_FAIL: + case WRITE_2_BYTES: + case WRITE_4_BYTES_FAIL: + case WRITE_2_BYTES_OFFSET: + case READ_SIZE_2: + _result_size = 2; + break; + case READ_4_BYTES: + case READ_4_BYTES_ERASED: + case READ_4_BYTES_MIXED: + case READ_4_BYTES_OFFSET: + case WRITE_4_BYTES: + case ERASE_4_BYTES: + case READ_SIZE_4: + _result_size = 4; + break; + default: + _result_size = 0; + } + + /* setup operation size */ + switch (command) { + case READ_2_BYTES: + case READ_2_BYTES_OFFSET_FAIL: + case WRITE_2_BYTES: + case WRITE_2_BYTES_OFFSET: + case WRITE_2_BYTES_OFFSET_FAIL: + case WRITE_SIZE_2: + _operation_size = 2; + break; + case READ_4_BYTES: + case READ_4_BYTES_ERASED: + case READ_4_BYTES_MIXED: + case READ_4_BYTES_OFFSET: + case READ_4_BYTES_FAIL: + case WRITE_4_BYTES: + case WRITE_4_BYTES_FAIL: + case ERASE_4_BYTES: + case READ_SIZE_4: + case WRITE_SIZE_4: + _operation_size = 4; + break; + default: + _operation_size = 0; + } + + /* setup offset */ + switch (command) { + case READ_2_BYTES_OFFSET_FAIL: + case WRITE_2_BYTES_OFFSET: + case WRITE_2_BYTES_OFFSET_FAIL: + _address = 2; + break; + default: + _address = 0; + } + + /* setup command success */ + switch (command) { + case READ_2_BYTES_OFFSET_FAIL: + case WRITE_2_BYTES_OFFSET_FAIL: + _success = false; + break; + default: + _success = true; + } + + /* call next command */ + switch (command & TEST_COMMAND_GROUP_MASK) { + case START_SESSION: + _driver->start_session(true); + break; + case END_SESSION: + _driver->end_session(); + break; + case READ_BYTES: + _driver->read_bytes(_address, _buffer, _operation_size); + break; + case WRITE_BYTES: + _driver->write_bytes(_address, _operation_data, _operation_size); + break; + case ERASE_BYTES: + _driver->erase_bytes(_address, 4); + break; + case READ_SIZE: + _driver->read_size(); + break; + case WRITE_SIZE: + _driver->write_size(_operation_size); + break; + case TERMINATE: + event_queue.break_dispatch(); + break; + default: + TEST_FAIL_MESSAGE("internal test failure - invalid command"); + } + } + + void evaluate_step(TestCommand_t command_completed) + { + /* check last command succeeded */ + TEST_ASSERT_EQUAL(command_completed, SEQUENCES[_sequence][_step]&TEST_COMMAND_GROUP_MASK); + + _step++; + + if (_step == MAX_STEP) { + TEST_FAIL_MESSAGE("internal test failure - too many steps"); + } + + execute_next_step(); + } + +private: + uint8_t _buffer[BUFFER_MAX]; + const uint8_t *_operation_data; + + NFCEEPROMDriver *_driver; + + TestSequence_t _sequence; + size_t _step; + size_t _result_size; + size_t _operation_size; + size_t _address; + bool _success; +}; + +/* test case running code */ + +static DriverTest *driver_test; +extern NFCEEPROMDriver *greentea_nfc_EEPROM_driver_get_instance(); + +utest::v1::status_t test_setup(const Case *const source, const size_t index_of_case) +{ + NFCEEPROMDriver *driver = greentea_nfc_EEPROM_driver_get_instance(); + driver_test = new DriverTest(driver); + + driver->set_event_queue(&event_queue); + driver->set_delegate(driver_test); + driver->reset(); + + TEST_ASSERT_NOT_EQUAL(0, driver->read_max_size()); + + return greentea_case_setup_handler(source, index_of_case); +} + +void session() +{ + driver_test->run_sequence(SESSION_TEST); +} + +void write_read() +{ + driver_test->run_sequence(WRITE_READ_TEST); +} + +void erase_bytes() +{ + driver_test->run_sequence(ERASE_TEST); +} + +void write_read_size() +{ + driver_test->run_sequence(WRITE_READ_SIZE_TEST); +} + +void truncate_size() +{ + driver_test->run_sequence(TRUNCATE_TEST); +} + +void write_bytes_truncated() +{ + driver_test->run_sequence(WRITE_TRUNCATE_TEST); +} + +void write_with_offset() +{ + driver_test->run_sequence(WRITE_WITH_OFFSET_TEST); +} + +void write_beyond_size() +{ + driver_test->run_sequence(WRITE_BEYOND_SIZE_TEST); +} + +utest::v1::status_t test_tear_down(const Case *const source, const size_t passed, + const size_t failed, const failure_t reason) +{ + delete driver_test; + + return greentea_case_teardown_handler(source, passed, failed, reason); +} + +/* test setup */ + +utest::v1::status_t test_init(const size_t number_of_cases) +{ + GREENTEA_SETUP(10, "default_auto"); + return greentea_test_setup_handler(number_of_cases); +} + +// Test cases +Case cases[] = { + Case("NFCEEPROM-SESSION", test_setup, session, test_tear_down), + Case("NFCEEPROM-WRITE-READ", test_setup, write_read, test_tear_down), + Case("NFCEEPROM-ERASE-BYTES", test_setup, erase_bytes, test_tear_down), + Case("NFCEEPROM-WRITE-READ-SIZE", test_setup, write_read_size, test_tear_down), + Case("NFCEEPROM-TRUNCATE-SIZE", test_setup, truncate_size, test_tear_down), + Case("NFCEEPROM-WRITE-BYTES-TRUNCATED", test_setup, write_bytes_truncated, test_tear_down), + Case("NFCEEPROM-WRITE-WITH-OFFSET", test_setup, write_with_offset, test_tear_down), + Case("NFCEEPROM-WRITE-BEYOND-SIZE", test_setup, write_beyond_size, test_tear_down) +}; + +Specification specification(test_init, cases); + +// Entry point into the tests +int main() +{ + return !Harness::run(specification); +}