/* * Copyright (c) 2022 Vestas Wind Systems A/S * * SPDX-License-Identifier: Apache-2.0 */ #include #include #include #include #include #ifdef CONFIG_ZTEST #include #endif /* CONFIG_ZTEST */ #define DT_DRV_COMPAT zephyr_fake_can struct fake_can_config { const struct can_driver_config common; }; struct fake_can_data { struct can_driver_data common; }; DEFINE_FAKE_VALUE_FUNC(int, fake_can_start, const struct device *); DEFINE_FAKE_VALUE_FUNC(int, fake_can_stop, const struct device *); DEFINE_FAKE_VALUE_FUNC(int, fake_can_set_timing, const struct device *, const struct can_timing *); DEFINE_FAKE_VALUE_FUNC(int, fake_can_set_timing_data, const struct device *, const struct can_timing *); DEFINE_FAKE_VALUE_FUNC(int, fake_can_get_capabilities, const struct device *, can_mode_t *); DEFINE_FAKE_VALUE_FUNC(int, fake_can_set_mode, const struct device *, can_mode_t); DEFINE_FAKE_VALUE_FUNC(int, fake_can_send, const struct device *, const struct can_frame *, k_timeout_t, can_tx_callback_t, void *); DEFINE_FAKE_VALUE_FUNC(int, fake_can_add_rx_filter, const struct device *, can_rx_callback_t, void *, const struct can_filter *); DEFINE_FAKE_VOID_FUNC(fake_can_remove_rx_filter, const struct device *, int); DEFINE_FAKE_VALUE_FUNC(int, fake_can_recover, const struct device *, k_timeout_t); DEFINE_FAKE_VALUE_FUNC(int, fake_can_get_state, const struct device *, enum can_state *, struct can_bus_err_cnt *); DEFINE_FAKE_VOID_FUNC(fake_can_set_state_change_callback, const struct device *, can_state_change_callback_t, void *); DEFINE_FAKE_VALUE_FUNC(int, fake_can_get_max_filters, const struct device *, bool); DEFINE_FAKE_VALUE_FUNC(int, fake_can_get_core_clock, const struct device *, uint32_t *); static int fake_can_get_core_clock_delegate(const struct device *dev, uint32_t *rate) { ARG_UNUSED(dev); /* Recommended CAN clock from CiA 601-3 */ *rate = MHZ(80); return 0; } #ifdef CONFIG_ZTEST static void fake_can_reset_rule_before(const struct ztest_unit_test *test, void *fixture) { ARG_UNUSED(test); ARG_UNUSED(fixture); RESET_FAKE(fake_can_start); RESET_FAKE(fake_can_stop); RESET_FAKE(fake_can_get_capabilities); RESET_FAKE(fake_can_set_mode); RESET_FAKE(fake_can_set_timing); RESET_FAKE(fake_can_set_timing_data); RESET_FAKE(fake_can_send); RESET_FAKE(fake_can_add_rx_filter); RESET_FAKE(fake_can_remove_rx_filter); RESET_FAKE(fake_can_get_state); RESET_FAKE(fake_can_recover); RESET_FAKE(fake_can_set_state_change_callback); RESET_FAKE(fake_can_get_max_filters); RESET_FAKE(fake_can_get_core_clock); /* Re-install default delegate for reporting the core clock */ fake_can_get_core_clock_fake.custom_fake = fake_can_get_core_clock_delegate; } ZTEST_RULE(fake_can_reset_rule, fake_can_reset_rule_before, NULL); #endif /* CONFIG_ZTEST */ static int fake_can_init(const struct device *dev) { /* Install default delegate for reporting the core clock */ fake_can_get_core_clock_fake.custom_fake = fake_can_get_core_clock_delegate; return 0; } static const struct can_driver_api fake_can_driver_api = { .start = fake_can_start, .stop = fake_can_stop, .get_capabilities = fake_can_get_capabilities, .set_mode = fake_can_set_mode, .set_timing = fake_can_set_timing, .send = fake_can_send, .add_rx_filter = fake_can_add_rx_filter, .remove_rx_filter = fake_can_remove_rx_filter, .get_state = fake_can_get_state, #ifdef CONFIG_CAN_MANUAL_RECOVERY_MODE .recover = fake_can_recover, #endif /* CONFIG_CAN_MANUAL_RECOVERY_MODE */ .set_state_change_callback = fake_can_set_state_change_callback, .get_core_clock = fake_can_get_core_clock, .get_max_filters = fake_can_get_max_filters, /* Recommended configuration ranges from CiA 601-2 */ .timing_min = { .sjw = 1, .prop_seg = 0, .phase_seg1 = 2, .phase_seg2 = 2, .prescaler = 1 }, .timing_max = { .sjw = 128, .prop_seg = 0, .phase_seg1 = 256, .phase_seg2 = 128, .prescaler = 32 }, #ifdef CONFIG_CAN_FD_MODE .set_timing_data = fake_can_set_timing_data, /* Recommended configuration ranges from CiA 601-2 */ .timing_data_min = { .sjw = 1, .prop_seg = 0, .phase_seg1 = 1, .phase_seg2 = 1, .prescaler = 1 }, .timing_data_max = { .sjw = 16, .prop_seg = 0, .phase_seg1 = 32, .phase_seg2 = 16, .prescaler = 32 }, #endif /* CONFIG_CAN_FD_MODE */ }; #ifdef CONFIG_CAN_FD_MODE #define FAKE_CAN_MAX_BITRATE 8000000 #else /* CONFIG_CAN_FD_MODE */ #define FAKE_CAN_MAX_BITRATE 1000000 #endif /* !CONFIG_CAN_FD_MODE */ #define FAKE_CAN_INIT(inst) \ static const struct fake_can_config fake_can_config_##inst = { \ .common = CAN_DT_DRIVER_CONFIG_INST_GET(inst, 0, FAKE_CAN_MAX_BITRATE), \ }; \ \ static struct fake_can_data fake_can_data_##inst; \ \ CAN_DEVICE_DT_INST_DEFINE(inst, fake_can_init, NULL, &fake_can_data_##inst, \ &fake_can_config_##inst, POST_KERNEL, \ CONFIG_CAN_INIT_PRIORITY, \ &fake_can_driver_api); DT_INST_FOREACH_STATUS_OKAY(FAKE_CAN_INIT)