takashi kadono
/
Nucleo_446
Color Oled(SSD1331) connect to STMicroelectronics Nucleo-F466
mbed-os/TESTS/nfc/eeprom/main.cpp
- Committer:
- kadonotakashi
- Date:
- 2018-10-11
- Revision:
- 3:f3764f852aa8
- Parent:
- 0:8fdf9a60065b
File content as of revision 3:f3764f852aa8:
/* * 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); }