diff --git a/I2CEeprom.lib b/I2CEeprom.lib old mode 100755 new mode 100644 diff --git a/LM75B.lib b/LM75B.lib deleted file mode 100644 index 500691f..0000000 --- a/LM75B.lib +++ /dev/null @@ -1 +0,0 @@ -https://developer.mbed.org/users/neilt6/code/LM75B/#7ac462ba84ac diff --git a/TESTS/API/BusInOut/BusInOut.cpp b/TESTS/API/BusInOut/BusInOut.cpp index d9f19ed..a346d0d 100644 --- a/TESTS/API/BusInOut/BusInOut.cpp +++ b/TESTS/API/BusInOut/BusInOut.cpp @@ -87,7 +87,7 @@ void businout_bidirectional_test(){ BusOut bout(MBED_CONF_APP_DIO_3,MBED_CONF_APP_DIO_5,MBED_CONF_APP_DIO_7,MBED_CONF_APP_DIO_9); bout = 0; volatile int x = 0; - while(x < 0x0F){ + while(x < 0x0F) { x++; bout.write(x); DEBUG_PRINTF("\r\n*********\r\nvalue of bin,bout,x is: 0x%x, 0x%x, 0x%x\r\n********\r\n",bin.read(),bout.read(),x); diff --git a/TESTS/Arduino/AnalogIn/AnalogIn.cpp b/TESTS/Arduino/AnalogIn/AnalogIn.cpp new file mode 100644 index 0000000..e2c2e1b --- /dev/null +++ b/TESTS/Arduino/AnalogIn/AnalogIn.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2016 ARM Limited + * + * 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. + */ +#if !DEVICE_ANALOGIN + #error [NOT_SUPPORTED] AnalogIn not supported on this platform, add 'DEVICE_ANALOGIN' definition to your platform. +#endif + +#include "mbed.h" +#include "greentea-client/test_env.h" +#include "unity.h" +#include "utest.h" +#include "ci_test_config.h" + +using namespace utest::v1; + +// Template to set one Analog pin as input and then cycle through the rest as outputs. +// As you turn more pins on the voltage on the ain pin will go up. +template +void AnalogInput_Test(){ + AnalogIn ain(ain_pin); + DEBUG_PRINTF("Tested pin %d for Arduino analog in capabilities\n", ain_pin); +} + +utest::v1::status_t test_setup(const size_t number_of_cases) { + GREENTEA_SETUP(30, "default_auto"); + return verbose_test_setup_handler(number_of_cases); +} + +utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason) { + greentea_case_failure_abort_handler(source, reason); + return STATUS_ABORT; +} + +Case cases[] = { + Case("Arduino - Analog Input Constructor on AIN_0", AnalogInput_Test, greentea_failure_handler), + Case("Arduino - Analog Input Constructor on AIN_1", AnalogInput_Test, greentea_failure_handler), + Case("Arduino - Analog Input Constructor on AIN_2", AnalogInput_Test, greentea_failure_handler), + Case("Arduino - Analog Input Constructor on AIN_3", AnalogInput_Test, greentea_failure_handler), + Case("Arduino - Analog Input Constructor on AIN_4", AnalogInput_Test, greentea_failure_handler), + Case("Arduino - Analog Input Constructor on AIN_5", AnalogInput_Test, greentea_failure_handler), +}; + +int main() { + // Formulate a specification and run the tests based on the Case array + Specification specification(test_setup, cases); + return !Harness::run(specification); +} diff --git a/TESTS/Arduino/AnalogOut/AnalogOut.cpp b/TESTS/Arduino/AnalogOut/AnalogOut.cpp new file mode 100644 index 0000000..d1894ca --- /dev/null +++ b/TESTS/Arduino/AnalogOut/AnalogOut.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2016 ARM Limited + * + * 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. + */ +#if !DEVICE_ANALOGOUT + #error [NOT_SUPPORTED] AnalogOut not supported on this platform, add 'DEVICE_ANALOGOUT' definition to your platform. +#endif + +#include "mbed.h" +#include "greentea-client/test_env.h" +#include "unity.h" +#include "utest.h" +#include "ci_test_config.h" + +using namespace utest::v1; + +template +void AnalogOutput_Test(){ + AnalogOut ain(aout_pin); + DEBUG_PRINTF("Tested pin %d for Arduino analog out capabilities\n", aout_pin); +} + +utest::v1::status_t test_setup(const size_t number_of_cases) { + GREENTEA_SETUP(30, "default_auto"); + return verbose_test_setup_handler(number_of_cases); +} + +utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason) { + greentea_case_failure_abort_handler(source, reason); + return STATUS_ABORT; +} + +Case cases[] = { + Case("Arduino - Analog Output Constructor on AOUT_0", AnalogOutput_Test, greentea_failure_handler), +}; + +int main() { + // Formulate a specification and run the tests based on the Case array + Specification specification(test_setup, cases); + return !Harness::run(specification); +} diff --git a/TESTS/Arduino/DigitalIO/DigitalIO.cpp b/TESTS/Arduino/DigitalIO/DigitalIO.cpp new file mode 100644 index 0000000..ca028a5 --- /dev/null +++ b/TESTS/Arduino/DigitalIO/DigitalIO.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2016 ARM Limited + * + * 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 "ci_test_config.h" + +using namespace utest::v1; + +template +void DigitalIO_Test(){ + DigitalOut dout(dio_pin); + DigitalIn din(dio_pin); + DEBUG_PRINTF("Tested pin %d for Arduino digital in/out capabilities\n", dio_pin); +} + +utest::v1::status_t test_setup(const size_t number_of_cases) { + GREENTEA_SETUP(30, "default_auto"); + return verbose_test_setup_handler(number_of_cases); +} + +utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason) { + greentea_case_failure_abort_handler(source, reason); + return STATUS_ABORT; +} + +Case cases[] = { + Case("Arduino - Digital IO Constructor on DIO_0", DigitalIO_Test, greentea_failure_handler), + Case("Arduino - Digital IO Constructor on DIO_1", DigitalIO_Test, greentea_failure_handler), + Case("Arduino - Digital IO Constructor on DIO_2", DigitalIO_Test, greentea_failure_handler), + Case("Arduino - Digital IO Constructor on DIO_3", DigitalIO_Test, greentea_failure_handler), + Case("Arduino - Digital IO Constructor on DIO_4", DigitalIO_Test, greentea_failure_handler), + Case("Arduino - Digital IO Constructor on DIO_5", DigitalIO_Test, greentea_failure_handler), + Case("Arduino - Digital IO Constructor on DIO_6", DigitalIO_Test, greentea_failure_handler), + Case("Arduino - Digital IO Constructor on DIO_7", DigitalIO_Test, greentea_failure_handler), + Case("Arduino - Digital IO Constructor on DIO_8", DigitalIO_Test, greentea_failure_handler), + Case("Arduino - Digital IO Constructor on DIO_9", DigitalIO_Test, greentea_failure_handler), +}; + +int main() { + // Formulate a specification and run the tests based on the Case array + Specification specification(test_setup, cases); + return !Harness::run(specification); +} diff --git a/TESTS/Arduino/I2C/I2C.cpp b/TESTS/Arduino/I2C/I2C.cpp new file mode 100644 index 0000000..99552b4 --- /dev/null +++ b/TESTS/Arduino/I2C/I2C.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2016 ARM Limited + * + * 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. + */ +#if !DEVICE_I2C + #error [NOT_SUPPORTED] I2C not supported on this platform, add 'DEVICE_I2C' definition to your platform. +#endif + +#include "mbed.h" +#include "greentea-client/test_env.h" +#include "unity.h" +#include "utest.h" +#include "ci_test_config.h" + +using namespace utest::v1; + +template +void I2C_Test(){ + I2C i2c(sda, scl); + DEBUG_PRINTF("Tested sda pin %d and scl pin %d for Arduino I2C capabilities\n", sda, scl); +} + +utest::v1::status_t test_setup(const size_t number_of_cases) { + GREENTEA_SETUP(30, "default_auto"); + return verbose_test_setup_handler(number_of_cases); +} + +utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason) { + greentea_case_failure_abort_handler(source, reason); + return STATUS_ABORT; +} + +Case cases[] = { + Case("Arduino - I2C Constructor on I2C_SDA/I2C_SCL", I2C_Test, greentea_failure_handler), +}; + +int main() { + // Formulate a specification and run the tests based on the Case array + Specification specification(test_setup, cases); + return !Harness::run(specification); +} diff --git a/TESTS/Arduino/Pwm/Pwm.cpp b/TESTS/Arduino/Pwm/Pwm.cpp new file mode 100644 index 0000000..9381d88 --- /dev/null +++ b/TESTS/Arduino/Pwm/Pwm.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2016 ARM Limited + * + * 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. + */ +#if !DEVICE_PWMOUT + #error [NOT_SUPPORTED] PWMOUT not supported on this platform, add 'DEVICE_PWMOUT' definition to your platform. +#endif + +#include "mbed.h" +#include "greentea-client/test_env.h" +#include "unity.h" +#include "utest.h" +#include "ci_test_config.h" + +using namespace utest::v1; + +template +void PWM_Test(){ + PwmOut pwm(pwm_pin); + DEBUG_PRINTF("Tested pin %d for Arduino digital in/out capabilities\n", pwm_pin); +} + +utest::v1::status_t test_setup(const size_t number_of_cases) { + GREENTEA_SETUP(30, "default_auto"); + return verbose_test_setup_handler(number_of_cases); +} + +utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason) { + greentea_case_failure_abort_handler(source, reason); + return STATUS_ABORT; +} + +Case cases[] = { + Case("Arduino - PWM Constructor on PWM_0", PWM_Test, greentea_failure_handler), + Case("Arduino - PWM Constructor on PWM_1", PWM_Test, greentea_failure_handler), + Case("Arduino - PWM Constructor on PWM_2", PWM_Test, greentea_failure_handler), + Case("Arduino - PWM Constructor on PWM_3", PWM_Test, greentea_failure_handler), +}; + +int main() { + // Formulate a specification and run the tests based on the Case array + Specification specification(test_setup, cases); + return !Harness::run(specification); +} diff --git a/TESTS/Arduino/SPI/SPI.cpp b/TESTS/Arduino/SPI/SPI.cpp new file mode 100644 index 0000000..d2b06e4 --- /dev/null +++ b/TESTS/Arduino/SPI/SPI.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2016 ARM Limited + * + * 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. + */ + +// check if SPI is supported on this device +#if !DEVICE_SPI + #error SPI is not supported on this platform, add 'DEVICE_SPI' definition to your platform. +#endif + +#include "mbed.h" +#include "greentea-client/test_env.h" +#include "unity.h" +#include "utest.h" +#include "ci_test_config.h" + +using namespace utest::v1; + +template +void SPI_Test(){ + SPI(mosi_pin, miso_pin, clk_pin); + DigitalOut cs(cs_pin); + DEBUG_PRINTF("Tested pins %d, %d, %d, and %d for Arduino SPI capabilities\n", mosi_pin, miso_pin, clk_pin, cs_pin); +} + +utest::v1::status_t test_setup(const size_t number_of_cases) { + GREENTEA_SETUP(30, "default_auto"); + return verbose_test_setup_handler(number_of_cases); +} + +utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason) { + greentea_case_failure_abort_handler(source, reason); + return STATUS_ABORT; +} + +Case cases[] = { + Case("Arduino - SPI Constructor", SPI_Test, greentea_failure_handler), +}; + +int main() { + // Formulate a specification and run the tests based on the Case array + Specification specification(test_setup, cases); + return !Harness::run(specification); +} diff --git a/TESTS/Level0/AnalogIn/AnalogIn.cpp b/TESTS/Level0/AnalogIn/AnalogIn.cpp new file mode 100644 index 0000000..82d62cd --- /dev/null +++ b/TESTS/Level0/AnalogIn/AnalogIn.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2016 ARM Limited + * + * 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. + * + * + */ + +#if !DEVICE_ANALOGIN + #error [NOT_SUPPORTED] AnalogIn not supported on this platform, add 'DEVICE_ANALOGIN' definition to your platform. +#endif + +#include "mbed.h" +#include "greentea-client/test_env.h" +#include "unity.h" +#include "utest.h" +#include "ci_test_config.h" + +#include "TestFramework.hpp" +#include + +using namespace utest::v1; + +// Static variables for managing the dynamic list of pins +std::vector< vector > TestFramework::pinout(TS_NC); +std::vector TestFramework::pin_iterators(TS_NC); + +// Initialize a test framework object +TestFramework test_framework; + +utest::v1::control_t test_level0_analogin(const size_t call_count) { + PinMap pin = test_framework.get_increment_pin(TestFramework::AnalogInput); + DEBUG_PRINTF("Running analog input constructor on pin %d\n", pin.pin); + TEST_ASSERT_MESSAGE(pin.pin != NC, "Pin is NC"); + + AnalogIn ain(pin.pin); + + return test_framework.reset_iterator(TestFramework::AnalogInput); +} + +Case cases[] = { + Case("Level 0 - Analog Input Constructor", test_level0_analogin, TestFramework::greentea_failure_handler), +}; + +int main() { + // Formulate a specification and run the tests based on the Case array + Specification specification(TestFramework::test_setup<30>, cases); + return !Harness::run(specification); +} diff --git a/TESTS/Level0/AnalogOut/AnalogOut.cpp b/TESTS/Level0/AnalogOut/AnalogOut.cpp new file mode 100644 index 0000000..ac767c3 --- /dev/null +++ b/TESTS/Level0/AnalogOut/AnalogOut.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2016 ARM Limited + * + * 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. + * + * + */ +#if !DEVICE_ANALOGOUT + #error [NOT_SUPPORTED] AnalogOut not supported on this platform, add 'DEVICE_ANALOGOUT' definition to your platform. +#endif + +#include "mbed.h" +#include "greentea-client/test_env.h" +#include "unity.h" +#include "utest.h" +#include "ci_test_config.h" + +#include "TestFramework.hpp" +#include + +using namespace utest::v1; + +// Static variables for managing the dynamic list of pins +std::vector< vector > TestFramework::pinout(TS_NC); +std::vector TestFramework::pin_iterators(TS_NC); + +// Initialize a test framework object +TestFramework test_framework; + +utest::v1::control_t test_level0_analogout(const size_t call_count) { + PinMap pin = test_framework.get_increment_pin(TestFramework::AnalogOutput); + DEBUG_PRINTF("Running analog output constructor on pin %d\n", pin.pin); + TEST_ASSERT_MESSAGE(pin.pin != NC, "Pin is NC"); + + AnalogOut ain(pin.pin); + + return test_framework.reset_iterator(TestFramework::AnalogOutput); +} + +Case cases[] = { + Case("Level 0 - Analog Output Constructor", test_level0_analogout, TestFramework::greentea_failure_handler), +}; + +int main() { + // Formulate a specification and run the tests based on the Case array + Specification specification(TestFramework::test_setup<30>, cases); + return !Harness::run(specification); +} diff --git a/TESTS/Level0/BusInOut/BusInOut.cpp b/TESTS/Level0/BusInOut/BusInOut.cpp new file mode 100644 index 0000000..cf61a5c --- /dev/null +++ b/TESTS/Level0/BusInOut/BusInOut.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2016 ARM Limited + * + * 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 "ci_test_config.h" + +#include "TestFramework.hpp" +#include + +#define BUS_SIZE 16 + +using namespace utest::v1; + +// Static variables for managing the dynamic list of pins +std::vector< vector > TestFramework::pinout(TS_NC); +std::vector TestFramework::pin_iterators(TS_NC); + +// Initialize a test framework object +TestFramework test_framework; + +utest::v1::control_t test_level0_businout(const size_t call_count) { + DEBUG_PRINTF("Running bus input/output constructor\n"); + + std::vector pins; // vector of pins that the bus will contain + while(pins.size() < BUS_SIZE){ // continually add pins until the bus is full + // check if more pins are available to add to bus + if(TestFramework::check_size(TestFramework::BusIO)) { + // fetch new pin + pins.push_back(test_framework.get_increment_pin(TestFramework::BusIO).pin); + } + + // if no more suitable pins are available, then add No-Connects until bus is full + else{ + pins.push_back((PinName)NC); + } + } + + DEBUG_PRINTF("Pins assigned to bus:\n pin[0] = %d\n pin[1] = %d\n pin[2] = %d\n pin[3] = %d\n pin[4] = %d\n pin[5] = %d\n pin[6] = %d\n pin[7] = %d\n pin[8] = %d\n pin[9] = %d\n pin[10] = %d\n pin[11] = %d\n pin[12] = %d\n pin[13] = %d\n pin[14] = %d\n pin[15] = %d\n",pins[0],pins[1],pins[2],pins[3],pins[4],pins[5],pins[6],pins[7],pins[8],pins[9],pins[10],pins[11],pins[12],pins[13],pins[14],pins[15]); + + // construct the bus with assigned pins + BusInOut bio(pins[0],pins[1],pins[2],pins[3],pins[4],pins[5],pins[6],pins[7],pins[8],pins[9],pins[10],pins[11],pins[12],pins[13],pins[14],pins[15]); + + return test_framework.reset_iterator(TestFramework::BusIO); +} + +Case cases[] = { + Case("Level 0 - Bus Input/Output Constructor", test_level0_businout, TestFramework::greentea_failure_handler), +}; + +int main() { + // Formulate a specification and run the tests based on the Case array + Specification specification(TestFramework::test_setup<30>, cases); + return !Harness::run(specification); +} diff --git a/TESTS/Level0/DigitalIO/DigitalIO.cpp b/TESTS/Level0/DigitalIO/DigitalIO.cpp new file mode 100644 index 0000000..30c1e58 --- /dev/null +++ b/TESTS/Level0/DigitalIO/DigitalIO.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2016 ARM Limited + * + * 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 "ci_test_config.h" + +#include "TestFramework.hpp" +#include + +using namespace utest::v1; + +// Static variables for managing the dynamic list of pins +std::vector< vector > TestFramework::pinout(TS_NC); +std::vector TestFramework::pin_iterators(TS_NC); + +// Initialize a test framework object +TestFramework test_framework; + +utest::v1::control_t test_level0_digitalio(const size_t call_count) { + PinMap pin = test_framework.get_increment_pin(TestFramework::DigitalIO); + DEBUG_PRINTF("Running digital io constructor on pin %d\n", pin.pin); + TEST_ASSERT_MESSAGE(pin.pin != NC, "Pin is NC"); + + DigitalOut dout(pin.pin); + DigitalIn din(pin.pin); + + return test_framework.reset_iterator(TestFramework::DigitalIO); +} + +Case cases[] = { + Case("Level 0 - DigitalIO Constructor", test_level0_digitalio, TestFramework::greentea_failure_handler), +}; + +int main() { + // Formulate a specification and run the tests based on the Case array + Specification specification(TestFramework::test_setup<30>, cases); + return !Harness::run(specification); +} diff --git a/TESTS/Level0/I2C/I2C.cpp b/TESTS/Level0/I2C/I2C.cpp new file mode 100644 index 0000000..04b351c --- /dev/null +++ b/TESTS/Level0/I2C/I2C.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2016 ARM Limited + * + * 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. + * + * + */ + +#if !DEVICE_I2C + #error [NOT_SUPPORTED] I2C not supported on this platform, add 'DEVICE_I2C' definition to your platform. +#endif + +#include "mbed.h" +#include "greentea-client/test_env.h" +#include "unity.h" +#include "utest.h" +#include "ci_test_config.h" + +#include "TestFramework.hpp" +#include + +using namespace utest::v1; + +// Static variables for managing the dynamic list of pins +std::vector< vector > TestFramework::pinout(TS_NC); +std::vector TestFramework::pin_iterators(TS_NC); + +// Initialize a test framework object +TestFramework test_framework; + +void construct_i2c(PinName sda, PinName scl) { + DEBUG_PRINTF("Running I2C Constructor on SDA pin %d and SCL pin %d\n", sda, scl); + TEST_ASSERT_MESSAGE(sda != NC, "SDA Pin is NC"); + TEST_ASSERT_MESSAGE(scl != NC, "SCL Pin is NC"); + + I2C i2c(sda, scl); +} + +utest::v1::control_t test_level0_i2c(const size_t call_count) { + return TestFramework::run_i2c(&construct_i2c); +} + +Case cases[] = { + Case("Level 0 - I2C Constructor", test_level0_i2c, TestFramework::greentea_failure_handler), +}; + +int main() { + // Formulate a specification and run the tests based on the Case array + Specification specification(TestFramework::test_setup<30>, cases); + return !Harness::run(specification); +} diff --git a/TESTS/Level0/Pwm/Pwm.cpp b/TESTS/Level0/Pwm/Pwm.cpp new file mode 100644 index 0000000..4b80a61 --- /dev/null +++ b/TESTS/Level0/Pwm/Pwm.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2016 ARM Limited + * + * 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. + * + * + */ + +#if !DEVICE_PWMOUT + #error [NOT_SUPPORTED] PWMOUT not supported on this platform, add 'DEVICE_PWMOUT' definition to your platform. +#endif + +#include "mbed.h" +#include "greentea-client/test_env.h" +#include "unity.h" +#include "utest.h" +#include "ci_test_config.h" + +#include "TestFramework.hpp" +#include + +using namespace utest::v1; + +// Static variables for managing the dynamic list of pins +std::vector< vector > TestFramework::pinout(TS_NC); +std::vector TestFramework::pin_iterators(TS_NC); + +// Initialize a test framework object +TestFramework test_framework; + +utest::v1::control_t test_level0_pwm(const size_t call_count) { + PinMap pin = test_framework.get_increment_pin(TestFramework::PWM); + DEBUG_PRINTF("Running pwm constructor on pin %d\n", pin.pin); + TEST_ASSERT_MESSAGE(pin.pin != NC, "pin is NC"); + + PwmOut pwm(pin.pin); + pwm.period(1.0f); + pwm.write(0.5f); + + return test_framework.reset_iterator(TestFramework::PWM); +} + +Case cases[] = { + Case("Level 0 - PWM Constructor", test_level0_pwm, TestFramework::greentea_failure_handler), +}; + +int main() { + // Formulate a specification and run the tests based on the Case array + Specification specification(TestFramework::test_setup<30>, cases); + return !Harness::run(specification); +} diff --git a/TESTS/Level0/SPI/SPI.cpp b/TESTS/Level0/SPI/SPI.cpp new file mode 100644 index 0000000..27d907f --- /dev/null +++ b/TESTS/Level0/SPI/SPI.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2016 ARM Limited + * + * 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. + * + * + */ + +#if !DEVICE_SPI + #error SPI is not supported on this platform, add 'DEVICE_SPI' definition to your platform. +#endif + +#include "mbed.h" +#include "greentea-client/test_env.h" +#include "unity.h" +#include "utest.h" +#include "ci_test_config.h" + +#include "TestFramework.hpp" +#include + +using namespace utest::v1; + +// Static variables for managing the dynamic list of pins +std::vector< vector > TestFramework::pinout(TS_NC); +std::vector TestFramework::pin_iterators(TS_NC); + +// Initialize a test framework object +TestFramework test_framework; + +void construct_spi(PinName pin_clk, PinName pin_miso, PinName pin_mosi, PinName pin_cs) { + DEBUG_PRINTF("Running SPI constructor on CLK pin %d, MISO pin %d, MOSI pin %d, and CS pin %d\n", pin_clk, pin_miso, pin_mosi, pin_cs); + TEST_ASSERT_MESSAGE(pin_clk != NC, "SPI CLK pin is NC"); + TEST_ASSERT_MESSAGE(pin_mosi != NC, "SPI MOSI Pin is NC"); + TEST_ASSERT_MESSAGE(pin_miso != NC, "SPI MISO Pin is NC"); + TEST_ASSERT_MESSAGE(pin_cs != NC, "SPI CS Pin is NC"); + + SPI(pin_mosi, pin_miso, pin_clk); + DigitalOut cs(pin_cs); +} + +utest::v1::control_t test_level0_spi(const size_t call_count) { + return test_framework.run_spi(&construct_spi); +} + +Case cases[] = { + Case("Level 0 - SPI Constructor", test_level0_spi, TestFramework::greentea_failure_handler), +}; + +int main() { + // Formulate a specification and run the tests based on the Case array + Specification specification(TestFramework::test_setup<60>, cases); + return !Harness::run(specification); +} diff --git a/TESTS/Level1/AnalogIn/AnalogIn.cpp b/TESTS/Level1/AnalogIn/AnalogIn.cpp new file mode 100644 index 0000000..13718b2 --- /dev/null +++ b/TESTS/Level1/AnalogIn/AnalogIn.cpp @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2016 ARM Limited + * + * 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. + * + * + */ + +#if !DEVICE_ANALOGIN + #error [NOT_SUPPORTED] AnalogIn not supported on this platform, add 'DEVICE_ANALOGIN' definition to your platform. +#endif + +#include "mbed.h" +#include "greentea-client/test_env.h" +#include "unity.h" +#include "utest.h" +#include "ci_test_config.h" + +#include "TestFramework.hpp" +#include + +using namespace utest::v1; + +// Static variables for managing the dynamic list of pins +std::vector< vector > TestFramework::pinout(TS_NC); +std::vector TestFramework::pin_iterators(TS_NC); + +// Initialize a test framework object +TestFramework test_framework; + +void test_analogin_execute(PinName pin, float tolerance, int iterations) { + DEBUG_PRINTF("Running analog input range test on pin %d\n", pin); + TEST_ASSERT_MESSAGE(pin != NC, "Pin is NC"); + + // Find all pins on the resistor ladder that are not the current pin + std::vector resistor_ladder_pins = TestFramework::find_resistor_ladder_pins(pin); + if (resistor_ladder_pins.size() < 5) + TEST_ASSERT_MESSAGE(false, "Error finding the resistor ladder pins"); + + // Create a bus with all of these pins + BusInOut outputs(resistor_ladder_pins[0],resistor_ladder_pins[1],resistor_ladder_pins[2],resistor_ladder_pins[3],resistor_ladder_pins[4]); + outputs.output(); + + DEBUG_PRINTF("Creating a resistive ladder bus with the following pins:\n pin[0] = %d\n pin[1] = %d\n pin[2] = %d\n pin[3] = %d\n pin[4] = %d\n", resistor_ladder_pins[0],resistor_ladder_pins[1],resistor_ladder_pins[2],resistor_ladder_pins[3],resistor_ladder_pins[4]); + + // construct designated analogIn pin + AnalogIn ain(pin); + + for (unsigned int i=0; i prev_value,"Analog Input did not increment. Check that you have assigned valid pins in mbed_app.json file") + + // Repeat the read multiple times to verify the output is not fluctuating + for (unsigned int j = 0; j, cases); + return !Harness::run(specification); +} diff --git a/TESTS/Level1/AnalogOut/AnalogOut.cpp b/TESTS/Level1/AnalogOut/AnalogOut.cpp new file mode 100644 index 0000000..36a55dc --- /dev/null +++ b/TESTS/Level1/AnalogOut/AnalogOut.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2016 ARM Limited + * + * 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. + * + * + */ + +#if !DEVICE_ANALOGOUT + #error [NOT_SUPPORTED] AnalogOut not supported on this platform, add 'DEVICE_ANALOGOUT' definition to your platform. +#endif + +#include "mbed.h" +#include "greentea-client/test_env.h" +#include "unity.h" +#include "utest.h" +#include "ci_test_config.h" + +#include "TestFramework.hpp" +#include + +using namespace utest::v1; + +// Static variables for managing the dynamic list of pins +std::vector< vector > TestFramework::pinout(TS_NC); +std::vector TestFramework::pin_iterators(TS_NC); + +// Initialize a test framework object +TestFramework test_framework; + +void test_analogout_execute(PinName pin, float tolerance, int iterations) { + DEBUG_PRINTF("Running analog output range test on pin %d\n", pin); + TEST_ASSERT_MESSAGE(pin != NC, "Pin is NC"); + + // Find all pins on the resistor ladder that are not the current pin + std::vector resistor_ladder_pins = TestFramework::find_resistor_ladder_pins(pin); + if (resistor_ladder_pins.size() < 5) + TEST_ASSERT_MESSAGE(false, "Error finding the resistor ladder pins"); + + AnalogIn ain(resistor_ladder_pins[0]); + + // Repeat to guarentee consistency + for (unsigned int i=0; i=(i-tolerance) && input<=(i+tolerance), "Analog input does not match analog output"); + } + } +} + +utest::v1::control_t test_level1_analogout(const size_t call_count) { + return TestFramework::test_level1_framework(TestFramework::AnalogOutput, TestFramework::CITS_AnalogOutput, &test_analogout_execute, 0.05, 10); +} + +Case cases[] = { + Case("Level 1 - Analog Output Range test (single pin)", test_level1_analogout, TestFramework::greentea_failure_handler), +}; + +int main() { + // Formulate a specification and run the tests based on the Case array + Specification specification(TestFramework::test_setup<30>, cases); + return !Harness::run(specification); +} diff --git a/TESTS/Level1/BusInOut/BusInOut.cpp b/TESTS/Level1/BusInOut/BusInOut.cpp new file mode 100644 index 0000000..c76f8e8 --- /dev/null +++ b/TESTS/Level1/BusInOut/BusInOut.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2016 ARM Limited + * + * 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 "ci_test_config.h" + +#include "TestFramework.hpp" +#include + +using namespace utest::v1; + +// Static variables for managing the dynamic list of pins +std::vector< vector > TestFramework::pinout(TS_NC); +std::vector TestFramework::pin_iterators(TS_NC); + +// Initialize a test framework object +TestFramework test_framework; + +void test_busio_execute(PinName pin, float tolerance, int iterations) { + DEBUG_PRINTF("Running analog input range test on pin %d\n", pin); + TEST_ASSERT_MESSAGE(pin != NC, "Pin is NC"); + + PinName pin_pair = TestFramework::find_pin_pair(pin); + BusInOut bio1(pin); + BusInOut bio2(pin_pair); + + bio1.output(); + bio2.input(); + bio1 = 0; + TEST_ASSERT_MESSAGE(bio2.read()==0, "Value read on bus does not equal value written."); + bio1 = 1; + TEST_ASSERT_MESSAGE(bio2.read()==1, "Value read on bus does not equal value written."); +} + +utest::v1::control_t test_level1_busio(const size_t call_count) { + return TestFramework::test_level2_framework(TestFramework::BusIO, TestFramework::CITS_DigitalIO, &test_busio_execute, 0.05, 10); +} + +Case cases[] = { + Case("Level 1 - Bus Input/Output pair test", test_level1_busio, TestFramework::greentea_failure_handler), +}; + +int main() { + // Formulate a specification and run the tests based on the Case array + Specification specification(TestFramework::test_setup<30>, cases); + return !Harness::run(specification); +} diff --git a/TESTS/Level1/DigitalIO/DigitalIO.cpp b/TESTS/Level1/DigitalIO/DigitalIO.cpp new file mode 100644 index 0000000..6147694 --- /dev/null +++ b/TESTS/Level1/DigitalIO/DigitalIO.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2016 ARM Limited + * + * 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 "ci_test_config.h" + +#include "TestFramework.hpp" +#include + +using namespace utest::v1; + +// Static variables for managing the dynamic list of pins +std::vector< vector > TestFramework::pinout(TS_NC); +std::vector TestFramework::pin_iterators(TS_NC); + +Timer timer; +int clocked_dio_toggle; + +// Initialize a test framework object +TestFramework test_framework; + +void dio_toggled(void) { + clocked_dio_toggle = timer.read_us(); +} + +void test_digitalio_execute(PinName pin, float tolerance, int iterations) { + DEBUG_PRINTF("Running digital io test on pin %d\n", pin); + TEST_ASSERT_MESSAGE(pin != NC, "Pin is NC"); + + PinName pinpair = TestFramework::find_pin_pair(pin); + DigitalOut dout(pinpair); + DigitalIn din(pin); + + // Verify Digital Input and Output can occur on the same pin + dout = 0; + TEST_ASSERT_MESSAGE(0 == din.read(),"Expected value to be 0, read value was not zero"); + dout = 1; + TEST_ASSERT_MESSAGE(1 == din.read(),"Expected value to be 1, read value was not one"); +} + +utest::v1::control_t test_level1_digitalio(const size_t call_count) { + return TestFramework::test_level1_framework(TestFramework::DigitalIO, TestFramework::CITS_DigitalIO, &test_digitalio_execute, 0.05, 10); +} + +Case cases[] = { + Case("Level 1 - Digital In/Out Range test (single pin)", test_level1_digitalio, TestFramework::greentea_failure_handler), +}; + +int main() { + // Formulate a specification and run the tests based on the Case array + Specification specification(TestFramework::test_setup<30>, cases); + return !Harness::run(specification); +} diff --git a/TESTS/Level1/I2C/I2C.cpp b/TESTS/Level1/I2C/I2C.cpp new file mode 100644 index 0000000..13b9c2b --- /dev/null +++ b/TESTS/Level1/I2C/I2C.cpp @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2016 ARM Limited + * + * 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. + * + * + */ + +#if !DEVICE_I2C + #error [NOT_SUPPORTED] I2C not supported on this platform, add 'DEVICE_I2C' definition to your platform. +#endif + +#include "mbed.h" +#include "greentea-client/test_env.h" +#include "unity.h" +#include "utest.h" +#include "ci_test_config.h" + +#include "TestFramework.hpp" +#include +#include +#include + +using namespace utest::v1; + +// Static variables for managing the dynamic list of pins +std::vector< vector > TestFramework::pinout(TS_NC); +std::vector TestFramework::pin_iterators(TS_NC); + +// Initialize a test framework object +TestFramework test_framework; +char* DEADBEEF = "DEADBEEF"; +char NULL_STR[128] = {0}; + +template +utest::v1::control_t test_level1_i2c(const size_t call_count) { + + // Check to see if the CI test shield I2C pins are connected to the board + PinName pin_scl = MBED_CONF_APP_I2C_SCL; + PinName pin_sda = MBED_CONF_APP_I2C_SDA; + if (TestFramework::find_pin(pin_scl, TestFramework::I2C_SCL)==-1 || + TestFramework::find_pin(pin_sda, TestFramework::I2C_SDA)==-1) { + return utest::v1::CaseNext; + } + + DEBUG_PRINTF("Running I2C constructor on SDA pin %d and SCL pin %d\n", pin_sda, pin_scl); + TEST_ASSERT_MESSAGE(pin_sda != NC, "SDA Pin is NC"); + TEST_ASSERT_MESSAGE(pin_scl != NC, "SCL Pin is NC"); + + I2CEeprom memory(pin_sda,pin_scl,MBED_CONF_APP_I2C_EEPROM_ADDR,32,0); + + // Generate a random string + char test_string[128] = {0}; + for (int i=0; i, TestFramework::greentea_failure_handler), + Case("Level 1 - I2C test - 10 byte (single pin set)", test_level1_i2c<10>, TestFramework::greentea_failure_handler), + Case("Level 1 - I2C test - 100 byte (single pin set)", test_level1_i2c<100>, TestFramework::greentea_failure_handler), +}; + +int main() { + // Formulate a specification and run the tests based on the Case array + Specification specification(TestFramework::test_setup<30>, cases); + return !Harness::run(specification); +} diff --git a/TESTS/Level1/Pwm/Pwm.cpp b/TESTS/Level1/Pwm/Pwm.cpp new file mode 100644 index 0000000..c402623 --- /dev/null +++ b/TESTS/Level1/Pwm/Pwm.cpp @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2016 ARM Limited + * + * 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. + * + * + */ + +#if !DEVICE_PWMOUT + #error [NOT_SUPPORTED] PWMOUT not supported on this platform, add 'DEVICE_PWMOUT' definition to your platform. +#endif + +#include "mbed.h" +#include "greentea-client/test_env.h" +#include "unity.h" +#include "utest.h" +#include "ci_test_config.h" + +#include "TestFramework.hpp" +#include + +using namespace utest::v1; + +// Static variables for managing the dynamic list of pins +std::vector< vector > TestFramework::pinout(TS_NC); +std::vector TestFramework::pin_iterators(TS_NC); + +// Initialize a test framework object +TestFramework test_framework; + +Timer timer; +int rise_count; +int fall_count; +int last_rise_time; +int duty_count; + +// Callback for a PWM rising edge +void callback_pwm_rise(void) { + rise_count++; + last_rise_time = timer.read_ms(); +} + +// Callback for a PWM falling edge +void callback_pwm_fall(void) { + fall_count++; + if (last_rise_time != 0) + duty_count = duty_count + (timer.read_ms() - last_rise_time); +} + +void test_pwm_execute(PinName pin, float dutycycle, int period) { + DEBUG_PRINTF("Running pwm test on pin %d\n", pin); + TEST_ASSERT_MESSAGE(pin != NC, "Pin is NC"); + + // Initialize + float tolerance = 0.05; + int iterations = 20; + float calculated_percent = iterations * tolerance; + if (calculated_percent < 1) calculated_percent = 1.0f; + fall_count = 0; + rise_count = 0; + last_rise_time = 0; + duty_count = 0; + + PwmOut pwm(pin); + timer.reset(); + InterruptIn iin(TestFramework::find_pin_pair(pin)); + iin.rise(callback_pwm_rise); + iin.fall(callback_pwm_fall); + + // Set the period + DEBUG_PRINTF("Period set to: %f, duty cycle set to: %f\n", (float)period/1000, dutycycle); + pwm.period((float)period/1000); + pwm.write(0); + DEBUG_PRINTF("Waiting for %dms\n", iterations * period); + + // Start the timer, write the duty cycle, and wait for completion + timer.start(); + pwm.write(dutycycle); + wait_ms(iterations * period); + + // Stop the timer, reset the IRQ for interrupts (cause it may not work on some platforms) and clear the PWM duty cycle + pwm.write(0); + iin.disable_irq(); + timer.stop(); + + // Run post calculations for verification + int rc = rise_count; + int fc = fall_count; + float avgTime = (float)duty_count / iterations; + float expectedTime = (float)period * dutycycle; + DEBUG_PRINTF("Expected time: %f, Avg Time: %f\n", expectedTime, avgTime); + DEBUG_PRINTF("rise count = %d, fall count = %d, expected count = %d\n", rc, fc, iterations); + TEST_ASSERT_MESSAGE( std::abs(rc-fc) <= calculated_percent, "There was more than a specific variance in number of rise vs fall cycles"); + TEST_ASSERT_MESSAGE( std::abs(iterations - rc) <= calculated_percent, "There was more than a specific variance in number of rise cycles seen and number expected."); + TEST_ASSERT_MESSAGE( std::abs(iterations - fc) <= calculated_percent, "There was more than a specific variance in number of fall cycles seen and number expected."); + // @TODO The following assert is a good check to have (comparing times) but fails on most platforms. Need to come up with a better way to do this test + // TEST_ASSERT_MESSAGE( std::abs(expectedTime - avgTime) <= calculated_percent,"Greater than a specific variance between expected and measured duty cycle"); +} + +template +utest::v1::control_t test_level1_pwm(const size_t call_count) { + return TestFramework::test_level1_framework(TestFramework::PWM, TestFramework::CITS_PWM, &test_pwm_execute, dutycycle*0.01f, period); +} + +Case cases[] = { + Case("Level 1 - PWM Frequency test (single pin) - 10ms", test_level1_pwm<50, 10>, TestFramework::greentea_failure_handler), + Case("Level 1 - PWM Frequency test (single pin) - 30ms", test_level1_pwm<50, 30>, TestFramework::greentea_failure_handler), + Case("Level 1 - PWM Frequency test (single pin) - 100ms", test_level1_pwm<50, 100>, TestFramework::greentea_failure_handler), + Case("Level 1 - PWM Duty cycle test (single pin) - 10%", test_level1_pwm<10, 10>, TestFramework::greentea_failure_handler), + Case("Level 1 - PWM Duty cycle test (single pin) - 50%", test_level1_pwm<50, 10>, TestFramework::greentea_failure_handler), + Case("Level 1 - PWM Duty cycle test (single pin) - 90%", test_level1_pwm<90, 10>, TestFramework::greentea_failure_handler), +}; + +int main() { + // Formulate a specification and run the tests based on the Case array + Specification specification(TestFramework::test_setup<30>, cases); + return !Harness::run(specification); +} diff --git a/TESTS/Level1/SPI/SPI.cpp b/TESTS/Level1/SPI/SPI.cpp new file mode 100644 index 0000000..8da1d12 --- /dev/null +++ b/TESTS/Level1/SPI/SPI.cpp @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2016 ARM Limited + * + * 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. + * + * + */ + +#if !DEVICE_SPI + #error SPI is not supported on this platform, add 'DEVICE_SPI' definition to your platform. +#endif + +#include "mbed.h" +#include "greentea-client/test_env.h" +#include "unity.h" +#include "utest.h" +#include "ci_test_config.h" + +#include "TestFramework.hpp" +#include +#include "FATFileSystem.h" +#include "SDBlockDevice.h" + +using namespace utest::v1; + +// Static variables for managing the dynamic list of pins +std::vector< vector > TestFramework::pinout(TS_NC); +std::vector TestFramework::pin_iterators(TS_NC); + +// Initialize a test framework object +TestFramework test_framework; + +template +utest::v1::control_t test_level1_spi(const size_t call_count) { + + // Verify that the CI test shield pins are connected to the SPI pins + PinName pin_clk = MBED_CONF_APP_SPI_CLK; + PinName pin_mosi = MBED_CONF_APP_SPI_MOSI; + PinName pin_miso = MBED_CONF_APP_SPI_MISO; + PinName pin_cs = MBED_CONF_APP_SPI_CS; + if (TestFramework::find_pin(pin_mosi, TestFramework::SPI_MOSI)==-1 || + TestFramework::find_pin(pin_miso, TestFramework::SPI_MISO)==-1 || + TestFramework::find_pin(pin_clk, TestFramework::SPI_CLK)==-1 || + TestFramework::find_pin(pin_cs, TestFramework::SPI_CS)==-1) { + return utest::v1::CaseNext; + } + + DEBUG_PRINTF("Running SPI constructor on CLK pin %d, MISO pin %d, MOSI pin %d, and CS pin %d\n", pin_clk, pin_miso, pin_mosi, pin_cs); + TEST_ASSERT_MESSAGE(pin_clk != NC, "SPI CLK pin is NC"); + TEST_ASSERT_MESSAGE(pin_mosi != NC, "SPI MOSI Pin is NC"); + TEST_ASSERT_MESSAGE(pin_miso != NC, "SPI MISO Pin is NC"); + TEST_ASSERT_MESSAGE(pin_cs != NC, "SPI CS Pin is NC"); + + // Get a random seed from the Greentea host test + srand(TestFramework::get_seed()); + + // Initialize the SD card and file system residing on the SD card + int error = 0; + SDBlockDevice sd(pin_mosi, pin_miso, pin_clk, pin_cs); + FATFileSystem fs("sd"); + sd.init(); + error = fs.mount(&sd); + TEST_ASSERT_MESSAGE(error==0,"SD file system mount failed."); + + // Iterate twice for consistency + for (int i=0; i<2; i++) { + + // Generate a random string + char test_string[128] = {0}; + for (int i=0; i 0,"Writing File to sd card failed"); // write data + fclose(File_write);// close file on SD + + // Close the old file, open the same file in read only mode, and read the file + FILE *File_read = fopen("/sd/test_card.txt", "r"); // open File_read + char test_string_read[128] = {0}; + fgets(test_string_read, 128, File_read); // read string from the file + DEBUG_PRINTF("Read '%s' in read test\nString comparison returns %d\n",test_string_read,strcmp(test_string_read,test_string)); + TEST_ASSERT_MESSAGE(strcmp(test_string_read,test_string) == 0,"String read does not match string written"); // test that strings match + fclose(File_read);// close file on SD + remove("/sd/test_card.txt"); + } + + // Unmount and de-initialize the SD card + error = fs.unmount(); + TEST_ASSERT_MESSAGE(error==0,"SD file system unmount failed."); + + sd.deinit(); + + return utest::v1::CaseNext; +} + +Case cases[] = { + Case("Level 1 - SPI test - 1 byte (single pin set)", test_level1_spi<1>, TestFramework::greentea_failure_handler), + Case("Level 1 - SPI test - 10 byte (single pin set)", test_level1_spi<10>, TestFramework::greentea_failure_handler), + Case("Level 1 - SPI test - 100 byte (single pin set)", test_level1_spi<100>, TestFramework::greentea_failure_handler), +}; + +int main() { + // Formulate a specification and run the tests based on the Case array + Specification specification(TestFramework::test_setup<30>, cases); + return !Harness::run(specification); +} diff --git a/TESTS/Level2/AnalogIn/AnalogIn.cpp b/TESTS/Level2/AnalogIn/AnalogIn.cpp new file mode 100644 index 0000000..5fcacd3 --- /dev/null +++ b/TESTS/Level2/AnalogIn/AnalogIn.cpp @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2016 ARM Limited + * + * 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. + * + * + */ + +#if !DEVICE_ANALOGIN + #error [NOT_SUPPORTED] AnalogIn not supported on this platform, add 'DEVICE_ANALOGIN' definition to your platform. +#endif + +#include "mbed.h" +#include "greentea-client/test_env.h" +#include "unity.h" +#include "utest.h" +#include "ci_test_config.h" + +#include "TestFramework.hpp" +#include + +using namespace utest::v1; + +// Static variables for managing the dynamic list of pins +std::vector< vector > TestFramework::pinout(TS_NC); +std::vector TestFramework::pin_iterators(TS_NC); + +// Initialize a test framework object +TestFramework test_framework; + +void test_analogin_execute(PinName pin, float tolerance, int iterations) { + DEBUG_PRINTF("Running analog input range test on pin %d\n", pin); + TEST_ASSERT_MESSAGE(pin != NC, "Pin is NC"); + + // Find all of the pins in the resistor ladder that are not the current pin, organize them into a bus inout + std::vector resistor_ladder_pins = TestFramework::find_resistor_ladder_pins(pin); + if (resistor_ladder_pins.size() < 5) + TEST_ASSERT_MESSAGE(false, "Error finding the resistor ladder pins"); + BusInOut outputs(resistor_ladder_pins[0],resistor_ladder_pins[1],resistor_ladder_pins[2],resistor_ladder_pins[3],resistor_ladder_pins[4]); + outputs.output(); + + AnalogIn ain(pin); + + for (unsigned int i=0; i prev_value,"Analog Input did not increment. Check that you have assigned valid pins in mbed_app.json file") + // Repeat multiple times to verify variability is minimal + for (unsigned int j = 0; j, cases); + return !Harness::run(specification); +} diff --git a/TESTS/Level2/BusInOut/BusInOut.cpp b/TESTS/Level2/BusInOut/BusInOut.cpp new file mode 100644 index 0000000..809a653 --- /dev/null +++ b/TESTS/Level2/BusInOut/BusInOut.cpp @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2016 ARM Limited + * + * 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 "ci_test_config.h" + +#include "TestFramework.hpp" +#include + +using namespace utest::v1; + +// Static variables for managing the dynamic list of pins +std::vector< vector > TestFramework::pinout(TS_NC); +std::vector TestFramework::pin_iterators(TS_NC); + +// Initialize a test framework object +TestFramework test_framework; + +// test that all pins can be marked as BusIn +void busin_define_test(){ + BusIn bin(MBED_CONF_APP_DIO_2,MBED_CONF_APP_DIO_3,MBED_CONF_APP_DIO_4,MBED_CONF_APP_DIO_5,MBED_CONF_APP_DIO_6,MBED_CONF_APP_DIO_7,MBED_CONF_APP_DIO_8,MBED_CONF_APP_DIO_9,MBED_CONF_APP_SPI_CS,MBED_CONF_APP_SPI_MOSI,MBED_CONF_APP_AIN_0,MBED_CONF_APP_AIN_1,MBED_CONF_APP_AIN_2,MBED_CONF_APP_AIN_3,MBED_CONF_APP_AIN_4,MBED_CONF_APP_AIN_5); + int x = 0; + x = bin.read(); + TEST_ASSERT_MESSAGE(true,"The fact that it hasnt error out proves this passes the sniff test"); +} + +// test that all pins can be marked as BusOut +void busout_define_test(){ + BusOut bout(MBED_CONF_APP_DIO_2,MBED_CONF_APP_DIO_3,MBED_CONF_APP_DIO_4,MBED_CONF_APP_DIO_5,MBED_CONF_APP_DIO_6,MBED_CONF_APP_DIO_7,MBED_CONF_APP_DIO_8,MBED_CONF_APP_DIO_9,MBED_CONF_APP_SPI_CS,MBED_CONF_APP_SPI_MOSI,MBED_CONF_APP_AIN_0,MBED_CONF_APP_AIN_1,MBED_CONF_APP_AIN_2,MBED_CONF_APP_AIN_3,MBED_CONF_APP_AIN_4,MBED_CONF_APP_AIN_5); + bout = 0; + volatile int x = 0; + while(x < 0xFF){ + DEBUG_PRINTF("value of x is: 0x%x\r\n",x); + x++; + bout.write(x); + } + TEST_ASSERT_MESSAGE(true,"The fact that it hasnt error out proves this passes the sniff test"); +} + +// test that all pins can be marked as BusInOut +void businout_define_test(){ + BusInOut bio1(MBED_CONF_APP_DIO_2,MBED_CONF_APP_DIO_4,MBED_CONF_APP_DIO_6,MBED_CONF_APP_DIO_8); + BusInOut bio2(MBED_CONF_APP_DIO_3,MBED_CONF_APP_DIO_5,MBED_CONF_APP_DIO_7,MBED_CONF_APP_DIO_9); + bio1.output(); + bio2.input(); + bio1 = 0x00; + volatile int x = 0x00; + + while(x < 0xF){ + x = (x<<1) +1; + bio1.output(); + bio1 = x; + bio2.input(); + volatile int y = bio2.read(); + DEBUG_PRINTF("value of x,bio is: 0x%x, 0x%x\r\n",x,y); + TEST_ASSERT_MESSAGE(y == x,"Value read on bus does not equal value written. "); + } + + x = 0x00; + while(x < 0xF){ + x = (x<<1) +1; + bio2.output(); + bio2 = x; + bio1.input(); + volatile int y = bio1.read(); + DEBUG_PRINTF("value of x,bio is: 0x%x, 0x%x\r\n",x,y); + TEST_ASSERT_MESSAGE(y == x,"Value read on bus does not equal value written. "); + } + + TEST_ASSERT_MESSAGE(true,"The fact that it hasnt error out proves this passes the sniff test"); +} + +// Test writing from one bus to another +void businout_bidirectional_test(){ + BusIn bin(MBED_CONF_APP_DIO_2,MBED_CONF_APP_DIO_4,MBED_CONF_APP_DIO_6,MBED_CONF_APP_DIO_8); + BusOut bout(MBED_CONF_APP_DIO_3,MBED_CONF_APP_DIO_5,MBED_CONF_APP_DIO_7,MBED_CONF_APP_DIO_9); + bout = 0; + volatile int x = 0; + while(x < 0x0F) { + x++; + bout.write(x); + DEBUG_PRINTF("value of bin,bout,x is: 0x%x, 0x%x, 0x%x\r\n",bin.read(),bout.read(),x); + TEST_ASSERT_MESSAGE(bin.read() == bout.read(),"Value read on bin does not equal value written on bout. ") + } + TEST_ASSERT_MESSAGE(true,"The fact that it hasnt error out proves this passes the sniff test"); +} + +Case cases[] = { + Case("Level 2 - Bus Input definable", busin_define_test, TestFramework::greentea_failure_handler), + Case("Level 2 - Bus Output definable", busout_define_test, TestFramework::greentea_failure_handler), + Case("Level 2 - Bus Input/Output range test", businout_define_test, TestFramework::greentea_failure_handler), + Case("Level 2 - Bus Input/Output range test 2", businout_bidirectional_test, TestFramework::greentea_failure_handler), +}; + +// Entry point into the tests +int main() { + // Formulate a specification and run the tests based on the Case array + Specification specification(TestFramework::test_setup<30>, cases); + return !Harness::run(specification); +} diff --git a/TESTS/Level2/DigitalIO/DigitalIO.cpp b/TESTS/Level2/DigitalIO/DigitalIO.cpp new file mode 100644 index 0000000..cda4a58 --- /dev/null +++ b/TESTS/Level2/DigitalIO/DigitalIO.cpp @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2016 ARM Limited + * + * 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 "ci_test_config.h" + +#include "TestFramework.hpp" +#include + +using namespace utest::v1; + +// Static variables for managing the dynamic list of pins +std::vector< vector > TestFramework::pinout(TS_NC); +std::vector TestFramework::pin_iterators(TS_NC); + +Timer timer; +int clocked_dio_toggle; + +// Initialize a test framework object +TestFramework test_framework; + +void dio_toggled(void) { + clocked_dio_toggle = timer.read_us(); +} + +void test_digitalio_execute(PinName pin, float tolerance, int iterations) { + DEBUG_PRINTF("Running digital io test on pin %d\n", pin); + TEST_ASSERT_MESSAGE(pin != NC, "Pin is NC"); + + PinName pinpair = TestFramework::find_pin_pair(pin); + DigitalOut dout(pinpair); + DigitalIn din(pin); + + // Verify Digital Input and Output can occur on the same pin + dout = 0; + TEST_ASSERT_MESSAGE(0 == din.read(),"Expected value to be 0, read value was not zero"); + dout = 1; + TEST_ASSERT_MESSAGE(1 == din.read(),"Expected value to be 1, read value was not one"); + int us_timeout = 10; + + for (unsigned int i=0; i, cases); + return !Harness::run(specification); +} diff --git a/TESTS/Level2/I2C/I2C.cpp b/TESTS/Level2/I2C/I2C.cpp new file mode 100644 index 0000000..9277fe5 --- /dev/null +++ b/TESTS/Level2/I2C/I2C.cpp @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2016 ARM Limited + * + * 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. + * + * + */ + +#if !DEVICE_I2C + #error [NOT_SUPPORTED] I2C not supported on this platform, add 'DEVICE_I2C' definition to your platform. +#endif + +#include "mbed.h" +#include "greentea-client/test_env.h" +#include "unity.h" +#include "utest.h" +#include "ci_test_config.h" + +#include "TestFramework.hpp" +#include +#include +#include + +using namespace utest::v1; + +// Static variables for managing the dynamic list of pins +std::vector< vector > TestFramework::pinout(TS_NC); +std::vector TestFramework::pin_iterators(TS_NC); + +// Initialize a test framework object +TestFramework test_framework; +char NULL_STR[128] = {0}; + +template +utest::v1::control_t test_level2_i2c(const size_t call_count) { + + // Check to see if the CI test shield I2C pins are connected to the board + PinName pin_scl = MBED_CONF_APP_I2C_SCL; + PinName pin_sda = MBED_CONF_APP_I2C_SDA; + if (TestFramework::find_pin(pin_scl, TestFramework::I2C_SCL)==-1 || TestFramework::find_pin(pin_sda, TestFramework::I2C_SDA)==-1) { + return utest::v1::CaseNext; + } + + DEBUG_PRINTF("Running I2C constructor on SDA pin %d and SCL pin %d\n", pin_sda, pin_scl); + TEST_ASSERT_MESSAGE(pin_sda != NC, "SDA Pin is NC"); + TEST_ASSERT_MESSAGE(pin_scl != NC, "SCL Pin is NC"); + + // Get a random seed from the Greentea host test + srand(TestFramework::get_seed()); + + I2CEeprom memory(pin_sda,pin_scl,MBED_CONF_APP_I2C_EEPROM_ADDR,32,0); + + // Generate a random string + char test_string[128] = {0}; + for (int i=0; i, TestFramework::greentea_failure_handler), + Case("Level 2 - I2C test - 10 byte (all pin set)", test_level2_i2c<10>, TestFramework::greentea_failure_handler), + Case("Level 2 - I2C test - 100 byte (all pin set)", test_level2_i2c<100>, TestFramework::greentea_failure_handler), +}; + +int main() { + // Formulate a specification and run the tests based on the Case array + Specification specification(TestFramework::test_setup<30>, cases); + return !Harness::run(specification); +} diff --git a/TESTS/Level2/Pwm/Pwm.cpp b/TESTS/Level2/Pwm/Pwm.cpp new file mode 100644 index 0000000..59ab203 --- /dev/null +++ b/TESTS/Level2/Pwm/Pwm.cpp @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2016 ARM Limited + * + * 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. + * + * + */ + +#if !DEVICE_PWMOUT + #error [NOT_SUPPORTED] PWMOUT not supported on this platform, add 'DEVICE_PWMOUT' definition to your platform. +#endif + +#include "mbed.h" +#include "greentea-client/test_env.h" +#include "unity.h" +#include "utest.h" +#include "ci_test_config.h" + +#include "TestFramework.hpp" +#include + +using namespace utest::v1; + +// Static variables for managing the dynamic list of pins +std::vector< vector > TestFramework::pinout(TS_NC); +std::vector TestFramework::pin_iterators(TS_NC); + +// Initialize a test framework object +TestFramework test_framework; + +Timer timer; +int rise_count; +int fall_count; +int last_rise_time; +int duty_count; + +// Callback for a PWM rising edge +void callback_pwm_rise(void) { + rise_count++; + last_rise_time = timer.read_ms(); +} + +// Callback for a PWM falling edge +void callback_pwm_fall(void) { + fall_count++; + if (last_rise_time != 0) + duty_count = duty_count + (timer.read_ms() - last_rise_time); +} + +void test_pwm_execute(PinName pin, float tolerance, int iterations, float dutycycle, int period) { + + // Initialize + float calculated_percent = iterations * tolerance; + if (calculated_percent < 1) calculated_percent = 1.0f; + fall_count = 0; + rise_count = 0; + last_rise_time = 0; + duty_count = 0; + + PwmOut pwm(pin); + timer.reset(); + InterruptIn iin(TestFramework::find_pin_pair(pin)); + iin.rise(callback_pwm_rise); + iin.fall(callback_pwm_fall); + + // Set the period + DEBUG_PRINTF("Duty cycle: %f, Period: %d\n", dutycycle, period); + pwm.period((float)period/1000); + pwm.write(0); + DEBUG_PRINTF("Waiting for %dms\n", iterations * period); + + // Start the timer, write the duty cycle, and wait for completion + timer.start(); + pwm.write(dutycycle); + wait_ms(iterations * period); + + // Stop the timer, reset the IRQ for interrupts (cause it may not work on some platforms) and clear the PWM duty cycle + pwm.write(0); + iin.disable_irq(); // This is here because otherwise it fails on some platforms + timer.stop(); + + // Run post calculations for verification + int rc = rise_count; + int fc = fall_count; + float avgTime = (float)duty_count / iterations; + float expectedTime = (float)period * dutycycle; + // DEBUG_PRINTF("Expected time: %f, Avg Time: %f\n", expectedTime, avgTime); + // DEBUG_PRINTF("rise count = %d, fall count = %d, expected count = %d\n", rc, fc, iterations); + TEST_ASSERT_MESSAGE( std::abs(rc-fc) <= calculated_percent, "There was more than a specific variance in number of rise vs fall cycles"); + TEST_ASSERT_MESSAGE( std::abs(iterations - rc) <= calculated_percent, "There was more than a specific variance in number of rise cycles seen and number expected."); + TEST_ASSERT_MESSAGE( std::abs(iterations - fc) <= calculated_percent, "There was more than a specific variance in number of fall cycles seen and number expected."); + // @TODO The following assert is a good check to have (comparing times) but fails on most platforms. Need to come up with a better way to do this test + // TEST_ASSERT_MESSAGE( std::abs(expectedTime - avgTime) <= calculated_percent,"Greater than a specific variance between expected and measured duty cycle"); + +} + +// Test case to just iterate through duty cycles +void test_pwm_dutycycle(PinName pin, float tolerance, int iterations) { + DEBUG_PRINTF("Running pwm test on pin %d\n", pin); + TEST_ASSERT_MESSAGE(pin != NC, "Pin is NC"); + + for (float dutycycle=0.05f; dutycycle <= 0.95f; dutycycle+=0.1f) { + test_pwm_execute(pin, tolerance, iterations, dutycycle, 10); + } + +} + +// Test case to just iterate through the period +void test_pwm_frequency(PinName pin, float tolerance, int iterations) { + DEBUG_PRINTF("Running pwm test on pin %d\n", pin); + TEST_ASSERT_MESSAGE(pin != NC, "Pin is NC"); + + for (int period=10; period<=200; period+=40) { + test_pwm_execute(pin, tolerance, iterations, 0.5f, period); + } +} + +// Test case that combines period and duty cycles +void test_pwm(PinName pin, float tolerance, int iterations) { + DEBUG_PRINTF("Running pwm test on pin %d\n", pin); + TEST_ASSERT_MESSAGE(pin != NC, "Pin is NC"); + + for (float dutycycle=0.2f; dutycycle <= 0.8f; dutycycle+=0.2f) { + for (int period=10; period<=210; period+=40) { + test_pwm_execute(pin, tolerance, iterations, dutycycle, period); + } + } +} + +utest::v1::control_t test_level2_pwm_frequency(const size_t call_count) { + return TestFramework::test_level2_framework(TestFramework::PWM, TestFramework::CITS_PWM, &test_pwm_frequency, 0.05f, 20); +} + +utest::v1::control_t test_level2_pwm_dutycycle(const size_t call_count) { + return TestFramework::test_level2_framework(TestFramework::PWM, TestFramework::CITS_PWM, &test_pwm_dutycycle, 0.05f, 20); +} + +utest::v1::control_t test_level2_pwm(const size_t call_count) { + return TestFramework::test_level2_framework(TestFramework::PWM, TestFramework::CITS_PWM, &test_pwm, 0.05f, 20); +} + +Case cases[] = { + Case("Level 2 - PWM Frequency test (all pins)", test_level2_pwm_frequency, TestFramework::greentea_failure_handler), + Case("Level 2 - PWM Dutycycle test (all pins)", test_level2_pwm_dutycycle, TestFramework::greentea_failure_handler), + Case("Level 2 - PWM all tests (all pins)", test_level2_pwm, TestFramework::greentea_failure_handler), +}; + +int main() { + // Formulate a specification and run the tests based on the Case array + Specification specification(TestFramework::test_setup<300>, cases); + return !Harness::run(specification); +} diff --git a/TESTS/Level2/SPI/SPI.cpp b/TESTS/Level2/SPI/SPI.cpp new file mode 100644 index 0000000..fe08e64 --- /dev/null +++ b/TESTS/Level2/SPI/SPI.cpp @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2016 ARM Limited + * + * 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. + * + * + */ + +#if !DEVICE_SPI + #error SPI is not supported on this platform, add 'DEVICE_SPI' definition to your platform. +#endif + +#include "mbed.h" +#include "greentea-client/test_env.h" +#include "unity.h" +#include "utest.h" +#include "ci_test_config.h" + +#include "TestFramework.hpp" +#include +#include "FATFileSystem.h" +#include "SDBlockDevice.h" + +using namespace utest::v1; + +// Static variables for managing the dynamic list of pins +std::vector< vector > TestFramework::pinout(TS_NC); +std::vector TestFramework::pin_iterators(TS_NC); + +// Initialize a test framework object +TestFramework test_framework; + +template +utest::v1::control_t test_level2_spi(const size_t call_count) { + + // Verify that the CI test shield pins are connected to the SPI pins + PinName pin_clk = MBED_CONF_APP_SPI_CLK; + PinName pin_mosi = MBED_CONF_APP_SPI_MOSI; + PinName pin_miso = MBED_CONF_APP_SPI_MISO; + PinName pin_cs = MBED_CONF_APP_SPI_CS; + if (TestFramework::find_pin(pin_mosi, TestFramework::SPI_MOSI)==-1 || + TestFramework::find_pin(pin_miso, TestFramework::SPI_MISO)==-1 || + TestFramework::find_pin(pin_clk, TestFramework::SPI_CLK)==-1 || + TestFramework::find_pin(pin_cs, TestFramework::SPI_CS)==-1) { + return utest::v1::CaseNext; + } + + DEBUG_PRINTF("Running SPI constructor on CLK pin %d, MISO pin %d, MOSI pin %d, and CS pin %d\n", pin_clk, pin_miso, pin_mosi, pin_cs); + TEST_ASSERT_MESSAGE(pin_clk != NC, "SPI CLK pin is NC"); + TEST_ASSERT_MESSAGE(pin_mosi != NC, "SPI MOSI Pin is NC"); + TEST_ASSERT_MESSAGE(pin_miso != NC, "SPI MISO Pin is NC"); + TEST_ASSERT_MESSAGE(pin_cs != NC, "SPI CS Pin is NC"); + + // Get a random seed from the Greentea host test + srand(TestFramework::get_seed()); + + // Initialize the SD card and file system residing on the SD card + int error = 0; + SDBlockDevice sd(pin_mosi, pin_miso, pin_clk, pin_cs); + FATFileSystem fs("sd"); + sd.init(); + error = fs.mount(&sd); + TEST_ASSERT_MESSAGE(error==0,"SD file system mount failed."); + + // Iterate twice for consistency + for (int i=0; i<2; i++) { + + // Generate a random string + char test_string[128] = {0}; + for (int j=0; j 0,"Writing File to sd card failed"); // write data + fclose(File_write);// close file on SD + + // Close the old file, open the same file in read only mode, and read the file + FILE *File_read = fopen(file_name, "r"); // open File_read + char test_string_read[128] = {0}; + fgets(test_string_read, 128, File_read); // read string from the file + DEBUG_PRINTF("Read '%s' in read test\n",test_string_read); + DEBUG_PRINTF("File name: '%s'\n",file_name); + TEST_ASSERT_MESSAGE(strcmp(test_string_read,test_string) == 0,"String read does not match string written"); // test that strings match + fclose(File_read);// close file on SD + remove(file_name); + } + + // Unmount and de-initialize the SD card + error = fs.unmount(); + TEST_ASSERT_MESSAGE(error==0,"SD file system unmount failed."); + + sd.deinit(); + + return utest::v1::CaseNext; +} + +Case cases[] = { + Case("Level 2 - SPI test - 1 byte (all pin sets)", test_level2_spi<1>, TestFramework::greentea_failure_handler), + Case("Level 2 - SPI test - 10 byte (all pin sets)", test_level2_spi<10>, TestFramework::greentea_failure_handler), + Case("Level 2 - SPI test - 100 byte (all pin sets)", test_level2_spi<100>, TestFramework::greentea_failure_handler), +}; + +int main() { + // Formulate a specification and run the tests based on the Case array + Specification specification(TestFramework::test_setup<30>, cases); + return !Harness::run(specification); +} diff --git a/TESTS/Level3/I2C/I2C.cpp b/TESTS/Level3/I2C/I2C.cpp new file mode 100644 index 0000000..c4fde1e --- /dev/null +++ b/TESTS/Level3/I2C/I2C.cpp @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2016 ARM Limited + * + * 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. + * + * + */ + +#if !DEVICE_I2C + #error [NOT_SUPPORTED] I2C not supported on this platform, add 'DEVICE_I2C' definition to your platform. +#endif + +#include "mbed.h" +#include "greentea-client/test_env.h" +#include "unity.h" +#include "utest.h" +#include "ci_test_config.h" + +#include "TestFramework.hpp" +#include +#include +#include + +using namespace utest::v1; + +// Static variables for managing the dynamic list of pins +std::vector< vector > TestFramework::pinout(TS_NC); +std::vector TestFramework::pin_iterators(TS_NC); + +// Initialize a test framework object +TestFramework test_framework; +char NULL_STR[128] = {0}; + +template +utest::v1::control_t test_level2_i2c(const size_t call_count) { + + // Check to see if the CI test shield I2C pins are connected to the board + PinName pin_scl = MBED_CONF_APP_I2C_SCL; + PinName pin_sda = MBED_CONF_APP_I2C_SDA; + if (TestFramework::find_pin(pin_scl, TestFramework::I2C_SCL)==-1 || TestFramework::find_pin(pin_sda, TestFramework::I2C_SDA)==-1) { + return utest::v1::CaseNext; + } + + DEBUG_PRINTF("Running I2C constructor on SDA pin %d and SCL pin %d\n", pin_sda, pin_scl); + TEST_ASSERT_MESSAGE(pin_sda != NC, "SDA Pin is NC"); + TEST_ASSERT_MESSAGE(pin_scl != NC, "SCL Pin is NC"); + + // Get a random seed from the Greentea host test + srand(TestFramework::get_seed()); + + I2CEeprom memory(pin_sda,pin_scl,MBED_CONF_APP_I2C_EEPROM_ADDR,32,0); + + // Generate a random string + char test_string[128] = {0}; + int rand_size = rand()%128+1; + for (int i=0; i, TestFramework::greentea_failure_handler), +}; + +int main() { + // Formulate a specification and run the tests based on the Case array + Specification specification(TestFramework::test_setup<30>, cases); + return !Harness::run(specification); +} diff --git a/TESTS/Level3/Pwm/Pwm.cpp b/TESTS/Level3/Pwm/Pwm.cpp new file mode 100644 index 0000000..85a196b --- /dev/null +++ b/TESTS/Level3/Pwm/Pwm.cpp @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2016 ARM Limited + * + * 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. + * + * + */ + +#if !DEVICE_PWMOUT + #error [NOT_SUPPORTED] PWMOUT not supported on this platform, add 'DEVICE_PWMOUT' definition to your platform. +#endif + +#include "mbed.h" +#include "greentea-client/test_env.h" +#include "unity.h" +#include "utest.h" +#include "ci_test_config.h" + +#include "TestFramework.hpp" +#include + +using namespace utest::v1; + +// Static variables for managing the dynamic list of pins +std::vector< vector > TestFramework::pinout(TS_NC); +std::vector TestFramework::pin_iterators(TS_NC); + +// Initialize a test framework object +TestFramework test_framework; + +Timer timer; +int rise_count; +int fall_count; +int last_rise_time; +int duty_count; + +// Callback for a PWM rising edge +void callback_pwm_rise(void) { + rise_count++; + last_rise_time = timer.read_ms(); +} + +// Callback for a PWM falling edge +void callback_pwm_fall(void) { + fall_count++; + if (last_rise_time != 0) + duty_count = duty_count + (timer.read_ms() - last_rise_time); +} + +void test_pwm_execute(PinName pin, float tolerance, int waveform_count, float dutycycle, int period) { + + // Initialize + float calculated_percent = waveform_count * tolerance; + if (calculated_percent < 1) calculated_percent = 1.0f; + fall_count = 0; + rise_count = 0; + last_rise_time = 0; + duty_count = 0; + + PwmOut pwm(pin); + timer.reset(); + InterruptIn iin(TestFramework::find_pin_pair(pin)); + iin.rise(callback_pwm_rise); + iin.fall(callback_pwm_fall); + + // Set the period + DEBUG_PRINTF("Duty cycle: %f, Period: %d\n", dutycycle, period); + pwm.period((float)period/1000); + pwm.write(0); + DEBUG_PRINTF("Waiting for %dms\n", waveform_count * period); + + // Start the timer, write the duty cycle, and wait for completion + timer.start(); + pwm.write(dutycycle); + wait_ms(waveform_count * period); + + // Stop the timer, reset the IRQ for interrupts (cause it may not work on some platforms) and clear the PWM duty cycle + pwm.write(0); + iin.disable_irq(); // This is here because otherwise it fails on some platforms + timer.stop(); + + // Run post calculations for verification + int rc = rise_count; + int fc = fall_count; + float avgTime = (float)duty_count / waveform_count; + float expectedTime = (float)period * dutycycle; + // DEBUG_PRINTF("Expected time: %f, Avg Time: %f\n", expectedTime, avgTime); + // DEBUG_PRINTF("rise count = %d, fall count = %d, expected count = %d\n", rc, fc, waveform_count); + TEST_ASSERT_MESSAGE( std::abs(rc-fc) <= calculated_percent, "There was more than a specific variance in number of rise vs fall cycles"); + TEST_ASSERT_MESSAGE( std::abs(waveform_count - rc) <= calculated_percent, "There was more than a specific variance in number of rise cycles seen and number expected."); + TEST_ASSERT_MESSAGE( std::abs(waveform_count - fc) <= calculated_percent, "There was more than a specific variance in number of fall cycles seen and number expected."); + // @TODO The following assert is a good check to have (comparing times) but fails on most platforms. Need to come up with a better way to do this test + // TEST_ASSERT_MESSAGE( std::abs(expectedTime - avgTime) <= calculated_percent,"Greater than a specific variance between expected and measured duty cycle"); + +} + +// Test case that combines period and duty cycles +void test_pwm(PinName pin, float tolerance, int iterations) { + DEBUG_PRINTF("Running pwm test on pin %d\n", pin); + TEST_ASSERT_MESSAGE(pin != NC, "Pin is NC"); + + // Get a random seed from the Greentea host test + srand(TestFramework::get_seed()); + + for (int i=0; i +utest::v1::control_t test_level2_pwm(const size_t call_count) { + return TestFramework::test_level2_framework(TestFramework::PWM, TestFramework::CITS_PWM, &test_pwm, 0.05f, iterations); +} + +Case cases[] = { + Case("Level 3 - PWM randomized", test_level2_pwm<10>, TestFramework::greentea_failure_handler), +}; + +int main() { + // Formulate a specification and run the tests based on the Case array + Specification specification(TestFramework::test_setup<200>, cases); + return !Harness::run(specification); +} diff --git a/TESTS/Level3/SPI/SPI.cpp b/TESTS/Level3/SPI/SPI.cpp new file mode 100644 index 0000000..af1ea3c --- /dev/null +++ b/TESTS/Level3/SPI/SPI.cpp @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2016 ARM Limited + * + * 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. + * + * + */ + +#if !DEVICE_SPI + #error SPI is not supported on this platform, add 'DEVICE_SPI' definition to your platform. +#endif + +#include "mbed.h" +#include "greentea-client/test_env.h" +#include "unity.h" +#include "utest.h" +#include "ci_test_config.h" + +#include "TestFramework.hpp" +#include +#include "FATFileSystem.h" +#include "SDBlockDevice.h" + +using namespace utest::v1; + +// Static variables for managing the dynamic list of pins +std::vector< vector > TestFramework::pinout(TS_NC); +std::vector TestFramework::pin_iterators(TS_NC); + +// Initialize a test framework object +TestFramework test_framework; + +template +utest::v1::control_t test_level3_spi(const size_t call_count) { + + // Verify that the CI test shield pins are connected to the SPI pins + PinName pin_clk = MBED_CONF_APP_SPI_CLK; + PinName pin_mosi = MBED_CONF_APP_SPI_MOSI; + PinName pin_miso = MBED_CONF_APP_SPI_MISO; + PinName pin_cs = MBED_CONF_APP_SPI_CS; + if (TestFramework::find_pin(pin_mosi, TestFramework::SPI_MOSI)==-1 || + TestFramework::find_pin(pin_miso, TestFramework::SPI_MISO)==-1 || + TestFramework::find_pin(pin_clk, TestFramework::SPI_CLK)==-1 || + TestFramework::find_pin(pin_cs, TestFramework::SPI_CS)==-1) { + return utest::v1::CaseNext; + } + + DEBUG_PRINTF("Running SPI constructor on CLK pin %d, MISO pin %d, MOSI pin %d, and CS pin %d\n", pin_clk, pin_miso, pin_mosi, pin_cs); + TEST_ASSERT_MESSAGE(pin_clk != NC, "SPI CLK pin is NC"); + TEST_ASSERT_MESSAGE(pin_mosi != NC, "SPI MOSI Pin is NC"); + TEST_ASSERT_MESSAGE(pin_miso != NC, "SPI MISO Pin is NC"); + TEST_ASSERT_MESSAGE(pin_cs != NC, "SPI CS Pin is NC"); + + // Get a random seed from the Greentea host test + srand(TestFramework::get_seed()); + + // Initialize the SD card and file system residing on the SD card + int error = 0; + SDBlockDevice sd(pin_mosi, pin_miso, pin_clk, pin_cs); + FATFileSystem fs("sd"); + sd.init(); + error = fs.mount(&sd); + TEST_ASSERT_MESSAGE(error==0,"SD file system mount failed."); + + // Iterate twice for consistency + for (int i=0; i<2; i++) { + + // Generate a random string + char test_string[128] = {0}; + int rand_size = rand()%128 + 1; + for (int j=0; j 0,"Writing File to sd card failed"); // write data + fclose(File_write);// close file on SD + + // Close the old file, open the same file in read only mode, and read the file + FILE *File_read = fopen(file_name, "r"); // open File_read + char test_string_read[128] = {0}; + fgets(test_string_read, 128, File_read); // read string from the file + DEBUG_PRINTF("Read '%s' in read test\n",test_string_read); + DEBUG_PRINTF("File name: '%s'\n",file_name); + TEST_ASSERT_MESSAGE(strcmp(test_string_read,test_string) == 0,"String read does not match string written"); // test that strings match + fclose(File_read);// close file on SD + remove(file_name); + } + + // Unmount and de-initialize the SD card + error = fs.unmount(); + TEST_ASSERT_MESSAGE(error==0,"SD file system unmount failed."); + + sd.deinit(); + + if (call_count, TestFramework::greentea_failure_handler), +}; + +int main() { + // Formulate a specification and run the tests based on the Case array + Specification specification(TestFramework::test_setup<30>, cases); + return !Harness::run(specification); +} diff --git a/TESTS/host_tests/rand_provider.py b/TESTS/host_tests/rand_provider.py new file mode 100644 index 0000000..ff11b9c --- /dev/null +++ b/TESTS/host_tests/rand_provider.py @@ -0,0 +1,57 @@ +# +# Copyright (c) 2016 ARM Limited +# +# 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. +# +from mbed_host_tests import BaseHostTest +import random +import sys + +class RandProvider(BaseHostTest): + """ Simple, basic host test's test runner waiting for serial port + output from MUT, no supervision over test running in MUT is executed. + """ + + __result = None + name = "rand_provider" + + def _callback_return_rand(self, key, value, timestamp): + # You've received {{return_rand;*}} + + # We will send DUT some data back... + # And now decide about test case result + if value == 'seed': + # Message payload/value was 'some_stuff' + # We can for example return true from test + seed = random.randint(0, sys.maxint) + self.send_kv("seed", "%d" % seed) + self.notify_complete(True) + else: + self.send_kv("print_this", "This not what I wanted :(") + self.notify_complete(False) + + def setup(self): + # Register callback for message 'return_rand' from DUT + self.register_callback("return_rand", self._callback_return_rand) + + # Initialize your host test here + # ... + + def result(self): + # Define your test result here + # Or use self.notify_complete(bool) to pass result anytime! + return self.__result + + def teardown(self): + # Release resources here after test is completed + pass \ No newline at end of file diff --git a/TestFramework.cpp b/TestFramework.cpp new file mode 100644 index 0000000..89ebe3e --- /dev/null +++ b/TestFramework.cpp @@ -0,0 +1,350 @@ +/* + * Copyright (c) 2016 ARM Limited + * + * 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 "TestFramework.hpp" + +/*///////////////////////////////////////////////////////////////////////////// +// Initialization // +/////////////////////////////////////////////////////////////////////////////*/ +TestFramework::TestFramework() { + map_pins(PinMap_ADC, AnalogInput); + map_pins(PinMap_DAC, AnalogOutput); + map_pins(PinMap_PWM, DigitalIO); + map_pins(PinMap_ADC, DigitalIO); + // map_pins(PinMap_DAC, DigitalIO); grabbing pin number from PeripheralPins.c, instead of the pin translation from mbed_app.json + map_pins(PinMap_I2C_SDA, DigitalIO); + map_pins(PinMap_I2C_SCL, DigitalIO); + map_pins(PinMap_SPI_SCLK, DigitalIO); + map_pins(PinMap_SPI_MOSI, DigitalIO); + map_pins(PinMap_SPI_MISO, DigitalIO); + map_pins(PinMap_SPI_SSEL, DigitalIO); + pinout[BusIO] = pinout[DigitalIO]; + map_pins(PinMap_PWM, PWM); + map_pins(PinMap_I2C_SDA, I2C_SDA); + map_pins(PinMap_I2C_SCL, I2C_SCL); + map_pins(PinMap_SPI_SCLK, SPI_CLK); + map_pins(PinMap_SPI_MOSI, SPI_MOSI); + map_pins(PinMap_SPI_MISO, SPI_MISO); + map_pins(PinMap_SPI_SSEL, SPI_CS); + setup_cits_pins(); +} + + +void TestFramework::setup_cits_pins() { + pinout[CITS_AnalogInput].push_back(construct_pinmap(MBED_CONF_APP_AIN_0)); + pinout[CITS_AnalogInput].push_back(construct_pinmap(MBED_CONF_APP_AIN_1)); + pinout[CITS_AnalogInput].push_back(construct_pinmap(MBED_CONF_APP_AIN_2)); + pinout[CITS_AnalogInput].push_back(construct_pinmap(MBED_CONF_APP_AIN_3)); + pinout[CITS_AnalogInput].push_back(construct_pinmap(MBED_CONF_APP_AIN_4)); + pinout[CITS_AnalogInput].push_back(construct_pinmap(MBED_CONF_APP_AIN_5)); + pinout[CITS_AnalogOutput].push_back(construct_pinmap(MBED_CONF_APP_AOUT)); + pinout[CITS_DigitalIO].push_back(construct_pinmap(MBED_CONF_APP_DIO_2)); + pinout[CITS_DigitalIO].push_back(construct_pinmap(MBED_CONF_APP_DIO_3)); + pinout[CITS_DigitalIO].push_back(construct_pinmap(MBED_CONF_APP_DIO_4)); + pinout[CITS_DigitalIO].push_back(construct_pinmap(MBED_CONF_APP_DIO_5)); + pinout[CITS_DigitalIO].push_back(construct_pinmap(MBED_CONF_APP_DIO_6)); + pinout[CITS_DigitalIO].push_back(construct_pinmap(MBED_CONF_APP_DIO_7)); + pinout[CITS_DigitalIO].push_back(construct_pinmap(MBED_CONF_APP_DIO_8)); + pinout[CITS_DigitalIO].push_back(construct_pinmap(MBED_CONF_APP_DIO_9)); + pinout[CITS_PWM].push_back(construct_pinmap(MBED_CONF_APP_PWM_0)); + pinout[CITS_PWM].push_back(construct_pinmap(MBED_CONF_APP_PWM_1)); + pinout[CITS_PWM].push_back(construct_pinmap(MBED_CONF_APP_PWM_2)); + pinout[CITS_PWM].push_back(construct_pinmap(MBED_CONF_APP_PWM_3)); + pinout[CITS_I2C_SDA].push_back(construct_pinmap(MBED_CONF_APP_I2C_SDA)); + pinout[CITS_I2C_SCL].push_back(construct_pinmap(MBED_CONF_APP_I2C_SCL)); + pinout[CITS_SPI_CLK].push_back(construct_pinmap(MBED_CONF_APP_SPI_CLK)); + pinout[CITS_SPI_MISO].push_back(construct_pinmap(MBED_CONF_APP_SPI_MISO)); + pinout[CITS_SPI_MOSI].push_back(construct_pinmap(MBED_CONF_APP_SPI_MOSI)); + pinout[CITS_SPI_CS].push_back(construct_pinmap(MBED_CONF_APP_SPI_CS)); +} + + +PinMap TestFramework::construct_pinmap(PinName pin) { + PinMap pinmap = {pin, 0, 0}; + return pinmap; +} + + +void TestFramework::map_pins(const PinMap pinmap[], Type pintype) { + int i = 0; + while(pinmap[i].pin != (PinName)NC) { + bool alreadyExists = false; + for (unsigned int j=0; j TestFramework::find_resistor_ladder_pins(PinName pin) { + std::vector resistor_ladder_pins; + for (unsigned int i = 0; i> seed; + return seed; +} + + +/*///////////////////////////////////////////////////////////////////////////// +// level0 // +// // +// Level 0 tests test the constructor and deconstructor of each pin of a // +// specified API. Every pin available for the specified API (ex. Analog in, // +// digital io, SPI), gets tested regardless of if it is connected to the CI // +// test shield. // +/////////////////////////////////////////////////////////////////////////////*/ +utest::v1::control_t TestFramework::run_i2c(void (*execution_callback)(PinName, PinName)) { + PinMap sda_pin = pinout[I2C_SDA][pin_iterators[I2C_SDA]]; + // Tag is used to identify if a test case had been executed (true) or not (false) + bool tag = false; + + // Itereate through the SCL pins to find a pin that matches the HW block of the SDA pin + while (pin_iterators[I2C_SCL] < pinout[I2C_SCL].size()) { + if (pinout[I2C_SCL][pin_iterators[I2C_SCL]].peripheral == sda_pin.peripheral) { + + // Execution has already occurred, but another SCL pin was found that matches the SDA pin. Queue up another test case + if (tag) {return utest::v1::CaseRepeatAll;} + // Matching SCL pin was found. Run the callback with the found pins + else { + execution_callback(sda_pin.pin, pinout[I2C_SCL][pin_iterators[I2C_SCL]].pin); + tag = true; + } + } + pin_iterators[I2C_SCL]++; + } + // All the SCL pins have been found for the identified SDA pin. Increment the SDA pin + if (!tag) {TEST_ASSERT(false);} + pin_iterators[I2C_SDA]++; + pin_iterators[I2C_SCL] = 0; + // Check to see if there are any more SDA pins available. Move on to the next test case if invalid and reset the counters + return reset_iterator(I2C_SDA); +} + + +utest::v1::control_t TestFramework::run_spi(void (*execution_callback)(PinName, PinName, PinName, PinName)) { + bool tag = false; // determines if execution_callback() was ran + + // Iterate through all CLK pins, finding the remaining SPI pins that have matching HW blocks + while (pin_iterators[SPI_CLK] < pinout[SPI_CLK].size()) { + + // Iterate through all the MISO pins + while (pin_iterators[SPI_MISO] < pinout[SPI_MISO].size()) { + + // Iterate through all the MOSI pins + while (pin_iterators[SPI_MOSI] < pinout[SPI_MOSI].size()) { + + // Iterate through all the CS pins + while (pin_iterators[SPI_CS] < pinout[SPI_CS].size()) { + // create local variables to help make code easier to read + PinMap CLK = pinout[SPI_CLK][pin_iterators[SPI_CLK]]; + PinMap MISO = pinout[SPI_MISO][pin_iterators[SPI_MISO]]; + PinMap MOSI = pinout[SPI_MOSI][pin_iterators[SPI_MOSI]]; + PinMap CS = pinout[SPI_CS][pin_iterators[SPI_CS]]; + + // ensure that chosen MISO, MOSI, and CS pins match the CLK pin's HW block + if ((MISO.peripheral == CLK.peripheral) && (MOSI.peripheral == CLK.peripheral) && (CS.peripheral == CLK.peripheral)){ + + // ensure that chosen SPI_CLK pin is not already assigned to another peripheral + if((CLK.pin != MISO.pin) && (CLK.pin != MOSI.pin) && (CLK.pin != CS.pin)){ + + // ensure that chosen SPI_MISO pin is not already assigned to another peripheral + if((MISO.pin != CLK.pin) && (MISO.pin != MOSI.pin) && (MISO.pin != CS.pin)){ + + // ensure that chosen SPI_MOSI pin is not already assigned to another peripheral + if((MOSI.pin != CLK.pin) && (MOSI.pin != MISO.pin) && (MOSI.pin != CS.pin)){ + + // ensure that chosen SPI_CS pin is not already assigned to another peripheral + if((CS.pin != CLK.pin) && (CS.pin != MOSI.pin) && (CS.pin != MISO.pin)){ + + // Found matching HW block pins. Run execution callback with them. + execution_callback(CLK.pin, MISO.pin, MOSI.pin, CS.pin); + tag = true; + } + } + } + } + } + pin_iterators[SPI_CS]++; // Increment and try next CS pin + if(tag) {return utest::v1::CaseRepeatAll;} + } + // Cycled through all CS pins. Reset CS iterator and increment MOSI iterator. + pin_iterators[SPI_CS] = 0; + pin_iterators[SPI_MOSI]++; + } + // Cycled through all MOSI pins. Reset MOSI iterator and increment MISO iterator. + pin_iterators[SPI_MOSI] = 0; + pin_iterators[SPI_MISO]++; + } + // Cycled through all MISO pins. Reset MISO iterator and increment CLK iterator. + pin_iterators[SPI_MISO] = 0; + pin_iterators[SPI_CLK]++; + } + + // All pins configurations have been iterated through. Reset pin iterators, run the CI test shield pin pair, and then move on to the next test case + pin_iterators[SPI_CLK] = 0; + pin_iterators[SPI_MISO] = 0; + pin_iterators[SPI_MOSI] = 0; + pin_iterators[SPI_CS] = 0; + execution_callback(MBED_CONF_APP_SPI_CLK, MBED_CONF_APP_SPI_MISO, MBED_CONF_APP_SPI_MOSI, MBED_CONF_APP_SPI_CS); + return utest::v1::CaseNext; +} + + +/*////////////////////////////////////////////////////////////////////////////// +// level1 // +// // +// Level 1 tests begin to test the full API for each hardware component. // +// The API can only be tested on pins mapped to the CI test shield, so the // +// following function iterates through all pins associated with the specified // +// hardware component until it finds a pin that is also mapped to the CI test // +// shield. Once a pin is found, it runs the callback passed in. Note that // +// only one pin is tested for each hardware component. // +//////////////////////////////////////////////////////////////////////////////*/ +utest::v1::control_t TestFramework::test_level1_framework(Type pintype, Type testtype, void (*execution_callback)(PinName, float, int), float floatdata, int intdata) { + while(check_size(pintype)) { + // Get current pin specified by the stored iterator + PinName pin = pinout[pintype][pin_iterators[pintype]].pin; + + // Check to see if current pin is available on the CI test shield + int index = find_pin(pin, testtype); + if (index != -1) { + // Current pin is mapped to the CI test shield. Run the callback, reset the iterator, and run the next case + execution_callback(pin, floatdata, intdata); + pin_iterators[pintype] = 0; + return utest::v1::CaseNext; + } + else{ + // Current pin was not mapped to CI test shield, try another pin + pin_iterators[pintype]++; + } + } +} + + +/*///////////////////////////////////////////////////////////////////////////// +// level2 // +// // +// Level 2 tests test the full API for each hardware similar to level 1 but // +// the difference is that the every pin mapped to the CI test shield (not // +// just a single pin) is tested. In addition, the tolerance and iterations // +// get a little bit more intense. // +/////////////////////////////////////////////////////////////////////////////*/ +utest::v1::control_t TestFramework::test_level2_framework(Type pintype, Type testtype, void (*execution_callback)(PinName, float, int), float floatdata, int intdata) { + // Get current pin specified by the stored iterator + PinName pin = pinout[pintype][pin_iterators[pintype]].pin; + // Check to see if that current pin is available on the CI test shield + int index = find_pin(pin, testtype); + // Tag is used to identify if a test case had been executed (true) or not (false) + bool tag = false; + // State: Execute + if (index != -1) { + // Pin was found, run the callback and specify the tag to true (run) + execution_callback(pin, floatdata, intdata); + tag = true; + } + // Search the remaining pins of the pintype to find a pin on the CI test shield + while (check_size(pintype)) { + // State: Increment iterator + pin_iterators[pintype]++; + pin = pinout[pintype][pin_iterators[pintype]].pin; + // Check to see if the current pin is available on the CI test shield + index = find_pin(pin, testtype); + + if (index != -1) { + // State: End case + // Pin was found, but execution had already occurred so queue up another test case + if (tag) { + return utest::v1::CaseRepeatAll; + // State: Execute + // Pin was found and execution has not occurred yet + } else { + execution_callback(pin, floatdata, intdata); + tag = true; + } + } + } + // State: End test + // All pins have been identified and run, reset the iterators and return back + return reset_iterator(pintype); +} diff --git a/TestFramework.hpp b/TestFramework.hpp new file mode 100644 index 0000000..2166645 --- /dev/null +++ b/TestFramework.hpp @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2016 ARM Limited + * + * 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. + * + * + */ +#ifndef TESTFRAMEWORK_H +#define TESTFRAMEWORK_H + +#include "cmsis.h" +#include "pinmap.h" +#include "PeripheralPins.h" +#include "mbed.h" + +#include "greentea-client/test_env.h" +#include "unity.h" +#include "utest.h" +#include "ci_test_config.h" + +#include +#include +#include +#include +#include +#include + +#define TEST_STRING_MAX 100 + +class TestFramework { +public: + + enum Type { + AnalogInput, + AnalogOutput, + DigitalIO, + PWM, + I2C_SDA, + I2C_SCL, + SPI_CLK, + SPI_MISO, + SPI_MOSI, + SPI_CS, + BusIO, + CITS_AnalogInput, + CITS_AnalogOutput, + CITS_DigitalIO, + CITS_PWM, + CITS_I2C_SDA, + CITS_I2C_SCL, + CITS_SPI_MOSI, + CITS_SPI_MISO, + CITS_SPI_CLK, + CITS_SPI_CS, + TS_NC + }; + + static std::vector< std::vector > pinout; + static std::vector pin_iterators; + + /** + * Constructor for the test framework. Add all of the PinMaps to the pinout, as well as CI test shield pins + **/ + TestFramework(); + + + template + static utest::v1::status_t test_setup(const size_t number_of_cases) { + GREENTEA_SETUP(timeout, "rand_provider"); + return utest::v1::verbose_test_setup_handler(number_of_cases); + } + + static utest::v1::status_t greentea_failure_handler(const utest::v1::Case *const source, const utest::v1::failure_t reason) { + greentea_case_failure_abort_handler(source, reason); + return utest::v1::STATUS_ABORT; + } + + /** + * Find a pin within the array of type pintype + * @param PinName pin to search for + * @param Type pin type to in which the pin has to be a part of + * @return index where the pin is found. Returns -1 if can't be found + **/ + static int find_pin(PinName pin, Type pintype); + + /** + * Find the pin that is connected to the specified pin via a resistor on the DIO HW bank + * @param PinName pin to find the corresponding pin connected by the resistor + * @return PinName pin that is connected to the input pin + **/ + static PinName find_pin_pair(PinName pin); + + /** + * Check to see if the pin iterator is pointing at a valid pin in the pinout + * @param Type pin type to validate + * @return bool if the pin iterator is a valid pin in the pinout + **/ + static bool check_size(Type pintype); + + /** + * Reset the iterator if all pins of the specified pin type have been looked at,
+ * or proceed to the next pin of the pin type if there are remaining pins + * @param Type pin type to reset + * @return control_t Case control statement to repeat or move on to the next case + **/ + static utest::v1::control_t reset_iterator(Type pintype); + + /** + * Get the current pin for a specific pin type, and incrememnt the iterator for that pin type + * @param Type pin type to retrieve and increment + * @return PinName current pin + **/ + static PinMap get_increment_pin(Type pintype); + + /** + * Find the resistor ladder pins that are not the specified pin + * @param PinName pin that should not be included in the resistor ladder + * @return vector list of resistor ladder pins + **/ + static std::vector find_resistor_ladder_pins(PinName pin); + + /** + * Get a randomized seed from Greentea's host test + * @return unsigned int random seed + **/ + static unsigned int get_seed(); + + /** + * Find a matching pin based on HW blocks to the current pin. Iterate the corresponding pin after test case execution + * @param Callback to a function to run once a pin pairing has been found + * @return control_t Case control to repeat or move on to next test cases + **/ + static utest::v1::control_t run_i2c(void (*execution_callback)(PinName, PinName)); + + /** + * Find a pin set (CLK, MISO, MOSI, CS) based on HW blocks that matches the current pin. Iterate the corresponding pins after test execution + * @param Callback to a function to run once a pin pairing has been found + * @return control_t Case control to repeat or move on to the next test cases + **/ + static utest::v1::control_t run_spi(void (*execution_callback)(PinName, PinName, PinName, PinName)); + + /** + * Find a pin of a specified test type and run a test case (passed in as a callback) + * @param Type type of pin to find to run the callback + * @param Type corresponding type of pin on the CI test shield + * @param Callback to the test case to run once a pin is found + * @param float data in float form to pass to the execution callback. Depends on callback + * @param int data in int form to pass to the execution callback. Depends on callback + * @return control_t identify to repeat or proceed to the next test case corresponding to the Specification + **/ + static utest::v1::control_t test_level1_framework(Type pintype, Type testtype, void (*execution_callback)(PinName, float, int), float floatdata, int intdata); + + /** + * Find pins of a specified test type and run a test case (passed in as a callback) + * Difference from the test_level1_framework function is this runs on ALL pins of a specified test type + * @param Type type of pin to find to run the callback + * @param Type corresponding type of pin on the CI test shield + * @param Callback to the test case to run once a pin is found + * @param float data in float form to pass to the execution callback. Depends on callback + * @param int data in int form to pass to the execution callback. Depends on callback + * @return control_t identify to repeat or proceed to the next test case corresponding to the Specification + **/ + static utest::v1::control_t test_level2_framework(Type pintype, Type testtype, void (*execution_callback)(PinName, float, int), float floatdata, int intdata); + + +private: + + /** + * Add all of the CI Test Shield pins to the pinout vector + **/ + void setup_cits_pins(); + + /** + * Construct a pinmap from a pin + **/ + PinMap construct_pinmap(PinName pin); + + /** + * Put pins from the specified pinmap into the pinout array indexed by pin type + * @param PinMap[] Found in the hal, specifies all the pins with a certain type + * @param Type which type the pins belong to (used to index into pinout) + **/ + void map_pins(const PinMap pinmap[], Type pintype); + +}; + +#endif //TESTFRAMEWORK_H diff --git a/mbed-os.lib b/mbed-os.lib index 0d6d412..208bfad 100644 --- a/mbed-os.lib +++ b/mbed-os.lib @@ -1 +1 @@ -https://github.com/ARMmbed/mbed-os/#f4864dc6429e1ff5474111d4e0f6bee36a759b1c +https://github.com/ARMmbed/mbed-os/#cc58a7fb0c979440ab13a7fb25c4acd12009ae1c \ No newline at end of file diff --git a/mbed_app.json b/mbed_app.json index 8460a9d..1e456b4 100644 --- a/mbed_app.json +++ b/mbed_app.json @@ -31,7 +31,7 @@ "PWM_1": "D5", "PWM_2": "D6", "PWM_3": "D9", - "DEBUG_MSG": 0 + "DEBUG_MSG": 1 }, "target_overrides": { "DISCO_L475VG_IOT01A": { @@ -87,6 +87,9 @@ "AOUT": "DAC0_OUT", "DIO_8":"PTC12", "DIO_9":"PTC4" + }, + "K22F": { + "AOUT": "DAC0_OUT" } } }