tests: drivers: can: timing: extend the test to cover data phase timing

Extend the CAN driver timing tests to cover data phase timing on CAN-FD
capable CAN controllers.

Signed-off-by: Henrik Brix Andersen <hebad@vestas.com>
This commit is contained in:
Henrik Brix Andersen 2022-03-25 08:38:11 +01:00 committed by Marti Bolivar
commit 29548dfb23

View file

@ -56,25 +56,22 @@ static const struct can_timing_test can_timing_tests[] = {
};
/**
* @brief CAN timing test fixture
* @brief List of CAN timing values to test for the data phase.
*/
struct can_timing_tests_fixture {
/** CAN device. */
const struct device *dev;
/** List of CAN timing test values. */
const struct can_timing_test *tests;
/** Number of CAN timing test list entries. */
const size_t test_count;
};
/**
* @brief CAN timing test fixture instance common to all test cases
*/
ZTEST_DMEM static struct can_timing_tests_fixture test_fixture = {
.dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_canbus)),
.tests = can_timing_tests,
.test_count = ARRAY_SIZE(can_timing_tests),
#ifdef CONFIG_CAN_FD_MODE
static const struct can_timing_test can_timing_data_tests[] = {
/** Standard bitrates. */
{ 500000, 875, false },
{ 1000000, 875, false },
/** Additional, valid sample points. */
{ 500000, 900, false },
{ 500000, 800, false },
/** Valid bitrate, invalid sample point. */
{ 500000, 1000, true },
/** Invalid CAN-FD bitrate, valid sample point. */
{ 8000000 + 1, 875, true },
};
#endif /* CONFIG_CAN_FD_MODE */
/**
* @brief Assert that a CAN timing struct matches the specified bitrate
@ -112,11 +109,10 @@ static void assert_bitrate_correct(const struct device *dev, struct can_timing *
* @param dev pointer to the device structure for the driver instance
* @param timing pointer to the CAN timing struct
*/
static void assert_timing_within_bounds(const struct device *dev, struct can_timing *timing)
static void assert_timing_within_bounds(struct can_timing *timing,
const struct can_timing *min,
const struct can_timing *max)
{
const struct can_timing *max = can_get_timing_max(dev);
const struct can_timing *min = can_get_timing_min(dev);
zassert_true(timing->sjw == CAN_SJW_NO_CHANGE, "sjw does not equal CAN_SJW_NO_CHANGE");
zassert_true(timing->prop_seg <= max->prop_seg, "prop_seg exceeds max");
@ -159,8 +155,11 @@ static void assert_sp_within_margin(struct can_timing *timing, uint16_t sp, uint
* @param dev pointer to the device structure for the driver instance
* @param test pointer to the set of CAN timing values
*/
static void test_timing_values(const struct device *dev, const struct can_timing_test *test)
static void test_timing_values(const struct device *dev, const struct can_timing_test *test,
bool data_phase)
{
const struct can_timing *max = NULL;
const struct can_timing *min = NULL;
struct can_timing timing = { 0 };
int err;
@ -168,7 +167,20 @@ static void test_timing_values(const struct device *dev, const struct can_timing
test->bitrate, test->sp / 10, test->sp % 10, test->invalid ? "invalid" : "valid");
timing.sjw = CAN_SJW_NO_CHANGE;
err = can_calc_timing(dev, &timing, test->bitrate, test->sp);
if (data_phase) {
if (IS_ENABLED(CONFIG_CAN_FD_MODE)) {
min = can_get_timing_min_data(dev);
max = can_get_timing_max_data(dev);
err = can_calc_timing_data(dev, &timing, test->bitrate, test->sp);
} else {
zassert_unreachable("data phase timing test without CAN-FD support");
}
} else {
min = can_get_timing_min(dev);
max = can_get_timing_max(dev);
err = can_calc_timing(dev, &timing, test->bitrate, test->sp);
}
if (test->invalid) {
zassert_equal(err, -EINVAL, "err %d, expected -EINVAL", err);
@ -178,7 +190,7 @@ static void test_timing_values(const struct device *dev, const struct can_timing
zassert_true(err <= SAMPLE_POINT_MARGIN, "sample point error %d too large", err);
assert_bitrate_correct(dev, &timing, test->bitrate);
assert_timing_within_bounds(dev, &timing);
assert_timing_within_bounds(&timing, min, max);
assert_sp_within_margin(&timing, test->sp, SAMPLE_POINT_MARGIN);
printk("OK, sample point error %d.%d%%\n", err / 10, err % 10);
@ -190,21 +202,45 @@ static void test_timing_values(const struct device *dev, const struct can_timing
*/
void test_timing(void)
{
const struct device *dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_canbus));
int i;
for (i = 0; i < test_fixture.test_count; i++) {
test_timing_values(test_fixture.dev, &test_fixture.tests[i]);
for (i = 0; i < ARRAY_SIZE(can_timing_tests); i++) {
test_timing_values(dev, &can_timing_tests[i], false);
}
}
/**
* @brief Test all CAN timing values for the data phase.
*/
#ifdef CONFIG_CAN_FD_MODE
void test_timing_data(void)
{
const struct device *dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_canbus));
int i;
for (i = 0; i < ARRAY_SIZE(can_timing_data_tests); i++) {
test_timing_values(dev, &can_timing_data_tests[i], true);
}
}
#else /* CONFIG_CAN_FD_MODE */
void test_timing_data(void)
{
ztest_test_skip();
}
#endif /* CONFIG_CAN_FD_MODE */
void test_main(void)
{
zassert_true(device_is_ready(test_fixture.dev), "CAN device not ready");
printk("testing on device %s\n", test_fixture.dev->name);
const struct device *dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_canbus));
k_object_access_grant(test_fixture.dev, k_current_get());
zassert_true(device_is_ready(dev), "CAN device not ready");
printk("testing on device %s\n", dev->name);
k_object_access_grant(dev, k_current_get());
ztest_test_suite(can_timing_tests,
ztest_user_unit_test(test_timing));
ztest_user_unit_test(test_timing),
ztest_user_unit_test(test_timing_data));
ztest_run_test_suite(can_timing_tests);
}