Skip to content

Commit

Permalink
devicetree: add devicetree/can.h
Browse files Browse the repository at this point in the history
This contains accessor macros for getting the maximum bitrate supported
by a CAN controller/transceiver combination.

Signed-off-by: Henrik Brix Andersen <[email protected]>
  • Loading branch information
henrikbrixandersen authored and MaureenHelm committed Mar 15, 2022
1 parent 71c3e4c commit 5e8399f
Show file tree
Hide file tree
Showing 9 changed files with 173 additions and 0 deletions.
1 change: 1 addition & 0 deletions CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,7 @@
/include/debug/gdbstub.h @ceolin
/include/device.h @tbursztyka @nashif
/include/devicetree.h @galak
/include/devicetree/can.h @henrikbrixandersen
/include/dt-bindings/clock/kinetis_mcg.h @henrikbrixandersen
/include/dt-bindings/clock/kinetis_scg.h @henrikbrixandersen
/include/dt-bindings/ethernet/xlnx_gem.h @ibirnbaum
Expand Down
1 change: 1 addition & 0 deletions MAINTAINERS.yml
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,7 @@ Documentation:
- subsys/net/l2/canbus/
- tests/subsys/canbus/
- dts/bindings/can/
- include/devicetree/can.h
- include/drivers/can.h
- samples/drivers/can/
- tests/drivers/can/
Expand Down
10 changes: 10 additions & 0 deletions doc/reference/devicetree/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,16 @@ Hardware specific APIs
The following APIs can also be used by including ``<devicetree.h>``;
no additional include is needed.

.. _devicetree-can-api:

CAN
===

These conveniences may be used for nodes which describe CAN
controllers/transceivers, and properties related to them.

.. doxygengroup:: devicetree-can

Clocks
======

Expand Down
8 changes: 8 additions & 0 deletions dts/bindings/test/vnd,can-controller.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Copyright (c) 2020 Vestas Wind Systems A/S
# SPDX-License-Identifier: Apache-2.0

description: Test CAN controller node

compatible: "vnd,can-controller"

include: can-controller.yaml
8 changes: 8 additions & 0 deletions dts/bindings/test/vnd,can-transceiver.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Copyright (c) 2020 Vestas Wind Systems A/S
# SPDX-License-Identifier: Apache-2.0

description: Test CAN transceiver node

compatible: "vnd,can-transceiver"

include: can-transceiver.yaml
1 change: 1 addition & 0 deletions include/devicetree.h
Original file line number Diff line number Diff line change
Expand Up @@ -3000,5 +3000,6 @@
#include <devicetree/zephyr.h>
#include <devicetree/ordinals.h>
#include <devicetree/pinctrl.h>
#include <devicetree/can.h>

#endif /* DEVICETREE_H */
86 changes: 86 additions & 0 deletions include/devicetree/can.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/**
* @file
* @brief CAN devicetree macro public API header file.
*/

/*
* Copyright (c) 2022 Vestas Wind Systems A/S
*
* SPDX-License-Identifier: Apache-2.0
*/

#ifndef ZEPHYR_INCLUDE_DEVICETREE_CAN_H_
#define ZEPHYR_INCLUDE_DEVICETREE_CAN_H_

#ifdef __cplusplus
extern "C" {
#endif

/**
* @defgroup devicetree-can Devicetree CAN API
* @ingroup devicetree
* @{
*/

/**
* @brief Get the maximum transceiver bitrate for a CAN controller
*
* The bitrate will be limited to the maximum bitrate supported by the CAN
* controller. If no CAN transceiver is present in the devicetree, the maximum
* bitrate will be that of the CAN controller.
*
* Example devicetree fragment:
*
* transceiver0: can-phy0 {
* compatible = "vnd,can-transceiver";
* max-bitrate = <1000000>;
* #phy-cells = <0>;
* };
*
* can0: can@... {
* compatible = "vnd,can-controller";
* phys = <&transceiver0>;
* };
*
* can1: can@... {
* compatible = "vnd,can-controller";
*
* can-transceiver {
* max-bitrate = <2000000>;
* };
* };
*
* Example usage:
*
* DT_CAN_TRANSCEIVER_MAX_BITRATE(DT_NODELABEL(can0), 5000000) // 1000000
* DT_CAN_TRANSCEIVER_MAX_BITRATE(DT_NODELABEL(can1), 5000000) // 2000000
* DT_CAN_TRANSCEIVER_MAX_BITRATE(DT_NODELABEL(can1), 1000000) // 1000000
*
* @param node_id node identifier
* @param max maximum bitrate supported by the CAN controller
* @return the maximum bitrate supported by the CAN controller/transceiver combination
*/
#define DT_CAN_TRANSCEIVER_MAX_BITRATE(node_id, max) \
COND_CODE_1(DT_NODE_HAS_PROP(node_id, phys), \
MIN(DT_PROP(DT_PHANDLE(node_id, phys), max_bitrate), max), \
MIN(DT_PROP_OR(DT_CHILD(node_id, can_transceiver), max_bitrate, max), max))

/**
* @brief Get the maximum transceiver bitrate for a DT_DRV_COMPAT CAN controller
* @param inst DT_DRV_COMPAT instance number
* @param max maximum bitrate supported by the CAN controller
* @return the maximum bitrate supported by the CAN controller/transceiver combination
* @see DT_CAN_TRANSCEIVER_MAX_BITRATE()
*/
#define DT_INST_CAN_TRANSCEIVER_MAX_BITRATE(inst, max) \
DT_CAN_TRANSCEIVER_MAX_BITRATE(DT_DRV_INST(inst), max)

/**
* @}
*/

#ifdef __cplusplus
}
#endif

#endif /* ZEPHYR_INCLUDE_DEVICETREE_CAN_H_ */
33 changes: 33 additions & 0 deletions tests/lib/devicetree/api/app.overlay
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,39 @@
status = "okay";
};

test_transceiver0: can-phy0 {
compatible = "vnd,can-transceiver";
label = "TEST_TRANSCEIVER_0";
status = "okay";
#phy-cells = <0>;
max-bitrate = <5000000>;
};

test_can0: can@55553333 {
compatible = "vnd,can-controller";
reg = < 0x55553333 0x1000 >;
sjw = <1>;
sample-point = <875>;
bus-speed = <125000>;
label = "TEST_CAN_CTRL_0";
status = "okay";
phys = <&test_transceiver0>;
};

test_can1: can@55554444 {
compatible = "vnd,can-controller";
reg = < 0x55554444 0x1000 >;
sjw = <1>;
sample-point = <875>;
bus-speed = <125000>;
label = "TEST_CAN_CTRL_1";
status = "okay";

can-transceiver {
max-bitrate = <2000000>;
};
};

/* there should only be one of these */
test_children: test-children {
compatible = "vnd,child-bindings";
Expand Down
25 changes: 25 additions & 0 deletions tests/lib/devicetree/api/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@
#define TEST_PWM_CTLR_1 DT_NODELABEL(test_pwm1)
#define TEST_PWM_CTLR_2 DT_NODELABEL(test_pwm2)

#define TEST_CAN_CTRL_0 DT_NODELABEL(test_can0)
#define TEST_CAN_CTRL_1 DT_NODELABEL(test_can1)

#define TEST_DMA_CTLR_1 DT_NODELABEL(test_dma1)
#define TEST_DMA_CTLR_2 DT_NODELABEL(test_dma2)

Expand Down Expand Up @@ -1095,6 +1098,27 @@ static void test_pwms(void)
zassert_equal(DT_INST_PWMS_FLAGS(0), 3, "");
}

#undef DT_DRV_COMPAT
#define DT_DRV_COMPAT vnd_can_controller
static void test_can(void)
{
/* DT_CAN_TRANSCEIVER_MAX_BITRATE */
zassert_equal(DT_CAN_TRANSCEIVER_MAX_BITRATE(TEST_CAN_CTRL_0, 1000000), 1000000, "");
zassert_equal(DT_CAN_TRANSCEIVER_MAX_BITRATE(TEST_CAN_CTRL_0, 5000000), 5000000, "");
zassert_equal(DT_CAN_TRANSCEIVER_MAX_BITRATE(TEST_CAN_CTRL_0, 8000000), 5000000, "");
zassert_equal(DT_CAN_TRANSCEIVER_MAX_BITRATE(TEST_CAN_CTRL_1, 1250000), 1250000, "");
zassert_equal(DT_CAN_TRANSCEIVER_MAX_BITRATE(TEST_CAN_CTRL_1, 2000000), 2000000, "");
zassert_equal(DT_CAN_TRANSCEIVER_MAX_BITRATE(TEST_CAN_CTRL_1, 5000000), 2000000, "");

/* DT_INST_CAN_TRANSCEIVER_MAX_BITRATE */
zassert_equal(DT_INST_CAN_TRANSCEIVER_MAX_BITRATE(0, 1000000), 1000000, "");
zassert_equal(DT_INST_CAN_TRANSCEIVER_MAX_BITRATE(0, 5000000), 5000000, "");
zassert_equal(DT_INST_CAN_TRANSCEIVER_MAX_BITRATE(0, 8000000), 5000000, "");
zassert_equal(DT_INST_CAN_TRANSCEIVER_MAX_BITRATE(1, 1250000), 1250000, "");
zassert_equal(DT_INST_CAN_TRANSCEIVER_MAX_BITRATE(1, 2000000), 2000000, "");
zassert_equal(DT_INST_CAN_TRANSCEIVER_MAX_BITRATE(1, 5000000), 2000000, "");
}

static void test_macro_names(void)
{
/* white box */
Expand Down Expand Up @@ -2248,6 +2272,7 @@ void test_main(void)
ztest_unit_test(test_io_channels),
ztest_unit_test(test_dma),
ztest_unit_test(test_pwms),
ztest_unit_test(test_can),
ztest_unit_test(test_macro_names),
ztest_unit_test(test_arrays),
ztest_unit_test(test_foreach_status_okay),
Expand Down

0 comments on commit 5e8399f

Please sign in to comment.