zephyr/drivers/can/can_fake.c
Henrik Brix Andersen e60da1bd64 drivers: can: fake: install default core clock delegate at driver init
Install the default delegate for reporting the CAN core clock frequency at
driver instance initialization. This allows using the default clock
configuration when not using ztest.

Signed-off-by: Henrik Brix Andersen <hebad@vestas.com>
2024-08-20 10:34:07 +02:00

176 lines
5.2 KiB
C

/*
* Copyright (c) 2022 Vestas Wind Systems A/S
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/device.h>
#include <zephyr/drivers/can.h>
#include <zephyr/drivers/can/can_fake.h>
#include <zephyr/fff.h>
#include <zephyr/sys/util.h>
#ifdef CONFIG_ZTEST
#include <zephyr/ztest.h>
#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)