Skip to content

Commit 044200f

Browse files
authored
Feature additions: PWM separation and concurrent testing
## Features: 2 features added: PWM separation and concurrent testing ### PWM separation Some MCUs do not have the ability to have rising and falling edge PWM triggers. We separated the PWM test into 3 separate tests: - Rising triggers - Falling triggers - Rising and falling triggers Test results now report when a specific trigger fails ### Concurrent tests Tests were designed to test specific implementations of mbed OS APIs. We added 3 additional tests to verify that crossover between APIs does not interfere. We test the following tests concurrently: - Communication APIs: Mixes SPI and I2C devices - GPI APIs: Mixes analog in/out, interrupt in, and digital in/out - Mixed APIs: Combines everything ### Feature requests Feature requests originally brought up here: - PWM separation: PR #58 - Concurrent tests: PR #57
2 parents dfce4e2 + f8cb240 commit 044200f

File tree

7 files changed

+1208
-262
lines changed

7 files changed

+1208
-262
lines changed

TESTS/API/PWM_fall/PWM_fall.cpp

+130
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
/*
2+
* Copyright (c) 2016 ARM Limited
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
//#error [NOT_SUPPORTED] PWM tests are still being written and validated, not for public use yet.
18+
19+
#if !DEVICE_PWMOUT
20+
#error [NOT_SUPPORTED] PWMOUT not supported on this platform, add 'DEVICE_PWMOUT' definition to your platform.
21+
#endif
22+
23+
#include "mbed.h"
24+
#include "greentea-client/test_env.h"
25+
#include "unity.h"
26+
#include "utest.h"
27+
#include <cmath>
28+
#include "ci_test_config.h"
29+
30+
using namespace utest::v1;
31+
32+
volatile int fall_count;
33+
void cbfn_fall(void){
34+
fall_count++;
35+
}
36+
37+
// Template to test that a PWM signal has the correct length by measuring the number falls
38+
// interrupts during a specified number of tests.
39+
template <PinName pwm_out_pin, PinName int_in_pin, int period_in_miliseconds, int num_tests>
40+
void PWM_Period_Test(){
41+
// Initialize PWM, InterruptIn, Timer, and Rising / Falling edge counts
42+
fall_count = 0;
43+
PwmOut pwm(pwm_out_pin);
44+
InterruptIn iin(int_in_pin);
45+
iin.fall(cbfn_fall);
46+
pwm.period((float)period_in_miliseconds/1000);
47+
48+
//Start Testing
49+
pwm.write(0.5f); // 50% duty cycle
50+
wait_ms(num_tests * period_in_miliseconds); // wait for pwm to run and counts to add up
51+
iin.disable_irq(); // This is here because otherwise it fails on some platforms
52+
int fc = fall_count; // grab the numbers to work with as the pwm may continue going
53+
54+
int expected_count = num_tests;
55+
56+
float ten_percent = (expected_count * 0.1f);
57+
float five_percent = (expected_count * 0.05f);
58+
float one_percent = (expected_count * 0.01f);
59+
60+
// fudge factor
61+
if(ten_percent < 1){
62+
ten_percent = 1;
63+
}
64+
if(five_percent < 1){
65+
five_percent = 1;
66+
}
67+
if(one_percent < 1){
68+
one_percent = 1;
69+
}
70+
71+
DEBUG_PRINTF("\r\n*****\r\n fall count = %d, expected count = %d",fc,expected_count);
72+
DEBUG_PRINTF("\r\n .10 = %f, .05 = %f, .01 = %f",ten_percent,five_percent,one_percent);
73+
74+
DEBUG_PRINTF("\r\n abs(expected-fc) = %d\r\n*****\r\n",std::abs(expected_count - fc));
75+
TEST_ASSERT_MESSAGE( std::abs(expected_count - fc) <= ten_percent, "There was more than 10 percent variance in number of fall cycles seen and number expected.");
76+
TEST_ASSERT_MESSAGE( std::abs(expected_count - fc) <= five_percent,"There was more than 5 percent variance in number of fall cycles seen and number expected.");
77+
//TEST_ASSERT_MESSAGE( std::abs(expected_count - fc) <= one_percent, "There was more than 1 percent variance in number of fall cycles seen and number expected.");
78+
}
79+
80+
// test if software constructor / destructor works
81+
void pwm_define_test(){
82+
PwmOut pwm0(MBED_CONF_APP_PWM_0);
83+
PwmOut pwm1(MBED_CONF_APP_PWM_1);
84+
PwmOut pwm2(MBED_CONF_APP_PWM_2);
85+
PwmOut pwm3(MBED_CONF_APP_PWM_3);
86+
87+
pwm0.period(1.0f);
88+
pwm1.period(1.0f);
89+
pwm2.period(1.0f);
90+
pwm3.period(1.0f);
91+
92+
pwm0.write(0.5f);
93+
pwm1.write(0.5f);
94+
pwm2.write(0.5f);
95+
pwm3.write(0.5f);
96+
97+
TEST_ASSERT_MESSAGE(true,"The fact that it hasnt errored out proves this passes the sniff test");
98+
}
99+
100+
utest::v1::status_t test_setup(const size_t number_of_cases){
101+
// Setup Greentea using a reasonable timeout in seconds
102+
GREENTEA_SETUP(200, "default_auto");
103+
return verbose_test_setup_handler(number_of_cases);
104+
}
105+
106+
// Handle test failures, keep testing, dont stop
107+
utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason){
108+
greentea_case_failure_abort_handler(source, reason);
109+
return STATUS_CONTINUE;
110+
}
111+
112+
// Test cases
113+
// TODO: take pin names from config file or generate from pinmap file
114+
Case cases[] = {
115+
// Test Creat PwmOut Objects
116+
Case("Pwm object definable", pwm_define_test,greentea_failure_handler), // test pwm object constructor works
117+
118+
// Test Frequency length by counting fall ticks
119+
Case("PWM_0 Frequency 30ms", PWM_Period_Test< MBED_CONF_APP_PWM_0, MBED_CONF_APP_DIO_2, 30, 100 >, greentea_failure_handler), // Test at 30ms 100 times, default 50%duty cycle
120+
Case("PWM_1 Frequency 30ms", PWM_Period_Test< MBED_CONF_APP_PWM_1, MBED_CONF_APP_DIO_4, 30, 100 >, greentea_failure_handler), // Test at 30ms 100 times, default 50%duty cycle
121+
Case("PWM_2 Frequency 30ms", PWM_Period_Test< MBED_CONF_APP_PWM_2, MBED_CONF_APP_DIO_7, 30, 100 >, greentea_failure_handler), // Test at 30ms 100 times, default 50%duty cycle
122+
Case("PWM_3 Frequency 30ms", PWM_Period_Test< MBED_CONF_APP_PWM_3, MBED_CONF_APP_DIO_8, 30, 100 >, greentea_failure_handler), // Test at 30ms 100 times, default 50%duty cycle
123+
};
124+
125+
Specification specification(test_setup, cases);
126+
127+
// Entry point into the tests
128+
int main(){
129+
return !Harness::run(specification);
130+
}

TESTS/API/PWM_rise/PWM_rise.cpp

+132
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
/*
2+
* Copyright (c) 2016 ARM Limited
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
//#error [NOT_SUPPORTED] PWM tests are still being written and validated, not for public use yet.
18+
19+
#if !DEVICE_PWMOUT
20+
#error [NOT_SUPPORTED] PWMOUT not supported on this platform, add 'DEVICE_PWMOUT' definition to your platform.
21+
#endif
22+
23+
#include "mbed.h"
24+
#include "greentea-client/test_env.h"
25+
#include "unity.h"
26+
#include "utest.h"
27+
#include <cmath>
28+
#include "ci_test_config.h"
29+
30+
using namespace utest::v1;
31+
32+
volatile int rise_count;
33+
void cbfn_rise(void){
34+
rise_count++;
35+
}
36+
37+
// Template to test that a PWM signal has the correct length by measuring the number of rise interrupts
38+
// interrupts during a specified number of tests.
39+
template <PinName pwm_out_pin, PinName int_in_pin, int period_in_miliseconds, int num_tests>
40+
void PWM_Period_Test(){
41+
// Initialize PWM, InterruptIn, Timer, and Rising / Falling edge counts
42+
rise_count = 0;
43+
PwmOut pwm(pwm_out_pin);
44+
InterruptIn iin(int_in_pin);
45+
iin.rise(cbfn_rise);
46+
pwm.period((float)period_in_miliseconds/1000);
47+
48+
//Start Testing
49+
pwm.write(0.5f); // 50% duty cycle
50+
wait_ms(num_tests * period_in_miliseconds); // wait for pwm to run and counts to add up
51+
iin.disable_irq(); // This is here because otherwise it fails on some platforms
52+
int rc = rise_count; // grab the numbers to work with as the pwm may continue going
53+
54+
int expected_count = num_tests;
55+
56+
float ten_percent = (expected_count * 0.1f);
57+
float five_percent = (expected_count * 0.05f);
58+
float one_percent = (expected_count * 0.01f);
59+
60+
// fudge factor
61+
if(ten_percent < 1){
62+
ten_percent = 1;
63+
}
64+
if(five_percent < 1){
65+
five_percent = 1;
66+
}
67+
if(one_percent < 1){
68+
one_percent = 1;
69+
}
70+
71+
DEBUG_PRINTF("\r\n*****\r\n rise count = %d, expected count = %d",rc,expected_count);
72+
DEBUG_PRINTF("\r\n .10 = %f, .05 = %f, .01 = %f",ten_percent,five_percent,one_percent);
73+
74+
DEBUG_PRINTF("\r\n abs(expected-rc) = %d",std::abs(expected_count - rc));
75+
TEST_ASSERT_MESSAGE( std::abs(expected_count - rc) <= ten_percent, "There was more than 10 percent variance in number of rise cycles seen and number expected.");
76+
TEST_ASSERT_MESSAGE( std::abs(expected_count - rc) <= five_percent,"There was more than 5 percent variance in number of rise cycles seen and number expected.");
77+
//TEST_ASSERT_MESSAGE( std::abs(expected_count - rc) <= one_percent, "There was more than 1 percent variance in number of rise cycles seen and number expected.");
78+
}
79+
80+
// test if software constructor / destructor works
81+
void pwm_define_test(){
82+
PwmOut pwm0(MBED_CONF_APP_PWM_0);
83+
PwmOut pwm1(MBED_CONF_APP_PWM_1);
84+
PwmOut pwm2(MBED_CONF_APP_PWM_2);
85+
PwmOut pwm3(MBED_CONF_APP_PWM_3);
86+
87+
pwm0.period(1.0f);
88+
pwm1.period(1.0f);
89+
pwm2.period(1.0f);
90+
pwm3.period(1.0f);
91+
92+
pwm0.write(0.5f);
93+
pwm1.write(0.5f);
94+
pwm2.write(0.5f);
95+
pwm3.write(0.5f);
96+
97+
TEST_ASSERT_MESSAGE(true,"The fact that it hasnt errored out proves this passes the sniff test");
98+
}
99+
100+
utest::v1::status_t test_setup(const size_t number_of_cases){
101+
// Setup Greentea using a reasonable timeout in seconds
102+
GREENTEA_SETUP(200, "default_auto");
103+
return verbose_test_setup_handler(number_of_cases);
104+
}
105+
106+
// Handle test failures, keep testing, dont stop
107+
utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason){
108+
greentea_case_failure_abort_handler(source, reason);
109+
return STATUS_CONTINUE;
110+
}
111+
112+
// Test cases
113+
// TODO: take pin names from config file or generate from pinmap file
114+
Case cases[] = {
115+
// test pwm object constructor works
116+
Case("Pwm object definable", pwm_define_test,greentea_failure_handler),
117+
118+
// Test Frequency length by counting rise ticks
119+
Case("PWM_0 Frequency 30ms", PWM_Period_Test< MBED_CONF_APP_PWM_0, MBED_CONF_APP_DIO_2, 30, 100 >, greentea_failure_handler), // Test at 30ms 100 times, default 50%duty cycle
120+
Case("PWM_1 Frequency 30ms", PWM_Period_Test< MBED_CONF_APP_PWM_1, MBED_CONF_APP_DIO_4, 30, 100 >, greentea_failure_handler), // Test at 30ms 100 times, default 50%duty cycle
121+
Case("PWM_2 Frequency 30ms", PWM_Period_Test< MBED_CONF_APP_PWM_2, MBED_CONF_APP_DIO_7, 30, 100 >, greentea_failure_handler), // Test at 30ms 100 times, default 50%duty cycle
122+
Case("PWM_3 Frequency 30ms", PWM_Period_Test< MBED_CONF_APP_PWM_3, MBED_CONF_APP_DIO_8, 30, 100 >, greentea_failure_handler), // Test at 30ms 100 times, default 50%duty cycle
123+
124+
};
125+
126+
Specification specification(test_setup, cases);
127+
128+
// Entry point into the tests
129+
int main()
130+
{
131+
return !Harness::run(specification);
132+
}

0 commit comments

Comments
 (0)