From 099b83af67978cdfaef038d7c1cb13c1b32deab8 Mon Sep 17 00:00:00 2001 From: Darian Leung Date: Mon, 11 Feb 2019 14:57:43 +0800 Subject: [PATCH] CAN: Add functions to clear queues and fix multiple bugs This commits adds the functions can_clear_transmit_queue() and can_clear_receive_queue(). Closes #2906 The following bug are fixed: - CAN_IO_UNUSED is now explicitly cast to enum type. Closes #2825 - Fix multiple documentation errors. Closes #2898, Closes #2794 - can_reconfigure_alerts() returns incorrect current_alerts. Closes #3028 - Add missing header file. Closes #3065 --- components/driver/can.c | 32 +- components/driver/include/driver/can.h | 31 +- docs/en/api-reference/peripherals/can.rst | 369 ++++++------------ .../main/can_network_example_master_main.c | 6 +- 4 files changed, 185 insertions(+), 253 deletions(-) diff --git a/components/driver/can.c b/components/driver/can.c index 0c20288f9..25b91ebaf 100644 --- a/components/driver/can.c +++ b/components/driver/can.c @@ -438,6 +438,8 @@ static void can_intr_handler_rx(BaseType_t *task_woken, int *alert_req) can_alert_handler(CAN_ALERT_RX_QUEUE_FULL, alert_req); } } + //Todo: Add Software Filters + //Todo: Check for data overrun of RX FIFO, then trigger alert } static void can_intr_handler_tx(can_status_reg_t *status, int *alert_req) @@ -496,7 +498,6 @@ static void can_intr_handler_main(void *arg) //Triggers when arbitration is lost can_intr_handler_arb_lost(&alert_req); } - //Todo: Check data overrun bug where interrupt does not trigger even when enabled //Handle TX/RX interrupts if (intr_reason.rx) { @@ -913,7 +914,7 @@ esp_err_t can_reconfigure_alerts(uint32_t alerts_enabled, uint32_t *current_aler CAN_CHECK(p_can_obj != NULL, ESP_ERR_INVALID_STATE); CAN_ENTER_CRITICAL(); uint32_t cur_alerts; - cur_alerts = can_read_alerts(&cur_alerts, 0); //Clear any unhandled alerts + can_read_alerts(&cur_alerts, 0); //Clear any unhandled alerts p_can_obj->alerts_enabled = alerts_enabled; //Update enabled alerts CAN_EXIT_CRITICAL(); @@ -977,3 +978,30 @@ esp_err_t can_get_status_info(can_status_info_t *status_info) return ESP_OK; } +esp_err_t can_clear_transmit_queue() +{ + //Check State + CAN_CHECK(p_can_obj != NULL, ESP_ERR_INVALID_STATE); + CAN_CHECK(p_can_obj->tx_queue != NULL, ESP_ERR_NOT_SUPPORTED); + + CAN_ENTER_CRITICAL(); + //If a message is currently undergoing transmission, the tx interrupt handler will decrement tx_msg_count + p_can_obj->tx_msg_count = (p_can_obj->control_flags & CTRL_FLAG_TX_BUFF_OCCUPIED) ? 1 : 0; + xQueueReset(p_can_obj->tx_queue); + CAN_EXIT_CRITICAL(); + + return ESP_OK; +} + +esp_err_t can_clear_receive_queue() +{ + //Check State + CAN_CHECK(p_can_obj != NULL, ESP_ERR_INVALID_STATE); + + CAN_ENTER_CRITICAL(); + p_can_obj->rx_msg_count = 0; + xQueueReset(p_can_obj->rx_queue); + CAN_EXIT_CRITICAL(); + + return ESP_OK; +} diff --git a/components/driver/include/driver/can.h b/components/driver/include/driver/can.h index af7b66e0b..da0613aac 100644 --- a/components/driver/include/driver/can.h +++ b/components/driver/include/driver/can.h @@ -19,6 +19,7 @@ extern "C" { #endif +#include "freertos/FreeRTOS.h" #include "esp_types.h" #include "esp_intr.h" #include "esp_err.h" @@ -105,7 +106,7 @@ extern "C" { #define CAN_EXTD_ID_MASK 0x1FFFFFFF /**< Bit mask for 29 bit Extended Frame Format ID */ #define CAN_STD_ID_MASK 0x7FF /**< Bit mask for 11 bit Standard Frame Format ID */ #define CAN_MAX_DATA_LEN 8 /**< Maximum number of data bytes in a CAN2.0B frame */ -#define CAN_IO_UNUSED (-1) /**< Marks GPIO as unused in CAN configuration */ +#define CAN_IO_UNUSED ((gpio_num_t) -1) /**< Marks GPIO as unused in CAN configuration */ /** @endcond */ /* ----------------------- Enum and Struct Definitions ---------------------- */ @@ -392,6 +393,34 @@ esp_err_t can_initiate_recovery(); */ esp_err_t can_get_status_info(can_status_info_t *status_info); +/** + * @brief Clear the transmit queue + * + * This function will clear the transmit queue of all messages. + * + * @note The transmit queue is automatically cleared when can_stop() or + * can_initiate_recovery() is called. + * + * @return + * - ESP_OK: Transmit queue cleared + * - ESP_ERR_INVALID_STATE: CAN driver is not installed or TX queue is disabled + */ +esp_err_t can_clear_transmit_queue(); + +/** + * @brief Clear the receive queue + * + * This function will clear the receive queue of all messages. + * + * @note The receive queue is automatically cleared when can_start() is + * called. + * + * @return + * - ESP_OK: Transmit queue cleared + * - ESP_ERR_INVALID_STATE: CAN driver is not installed + */ +esp_err_t can_clear_receive_queue(); + #ifdef __cplusplus } #endif diff --git a/docs/en/api-reference/peripherals/can.rst b/docs/en/api-reference/peripherals/can.rst index e3b236e61..d24cbd7f6 100644 --- a/docs/en/api-reference/peripherals/can.rst +++ b/docs/en/api-reference/peripherals/can.rst @@ -6,12 +6,10 @@ Controller Area Network (CAN) Overview -------- -The ESP32's peripherals contains a CAN Controller that supports Standard Frame -Format (16-bit ID) and Extended Frame Format (29-bit ID) of the CAN2.0B specification. +The ESP32's peripherals contains a CAN Controller that supports Standard Frame Format (11-bit ID) and Extended Frame Format (29-bit ID) of the CAN2.0B specification. .. warning:: - The ESP32 CAN controller is not compatible with CAN FD frames and will interpret - such frames as errors. + The ESP32 CAN controller is not compatible with CAN FD frames and will interpret such frames as errors. This programming guide is split into the following sections: @@ -34,35 +32,22 @@ Basic CAN Concepts ------------------ .. note:: - The following section only covers the basic aspects of CAN. For full details, - see the CAN2.0B specification + The following section only covers the basic aspects of CAN. For full details, see the CAN2.0B specification -The CAN protocol is a multi-master, multi-cast communication protocol with error -detection/signalling and inbuilt message prioritization. The CAN protocol is -commonly used as a communication bus in automotive applications. +The CAN protocol is a multi-master, multi-cast communication protocol with error detection/signalling and inbuilt message prioritization. The CAN protocol is commonly used as a communication bus in automotive applications. **Multi-master:** Any node in a CAN bus is allowed initiate the transfer of data. -**Multi-cast:** When a node transmits a message, all nodes are able to receive -the message (broadcast). However some nodes can selective choose which messages -to accept via the use of acceptance filtering (multi-cast). +**Multi-cast:** When a node transmits a message, all nodes are able to receive the message (broadcast). However some nodes can selective choose which messages to accept via the use of acceptance filtering (multi-cast). -**Error Detection and Signalling:** Every CAN node will constantly monitor the -CAN bus. When any node detects an error, it will signal the error by transmitting an error -frame. Other nodes will receive the error frame and transmit their own error frames -in response. This will result in an error detection being propagated to all nodes on -the bus. +**Error Detection and Signalling:** Every CAN node will constantly monitor the CAN bus. When any node detects an error, it will signal the error by transmitting an error frame. Other nodes will receive the error frame and transmit their own error frames in response. This will result in an error detection being propagated to all nodes on the bus. -**Message Priorities:** If two nodes attempt to transmit simultaneously, the -node transmitting the message with the lower ID will win arbitration. All other -nodes will become receivers ensuring there is at most one transmitter at any time. +**Message Priorities:** If two nodes attempt to transmit simultaneously, the node transmitting the message with the lower ID will win arbitration. All other nodes will become receivers ensuring there is at most one transmitter at any time. CAN Message Frames ^^^^^^^^^^^^^^^^^^ -The CAN2.0B specification contains two frame formats known as **Extended Frame** -and **Standard Frame** which contain 29-bit IDs and 11-bit IDs respectively. -A CAN message consists of the following components +The CAN2.0B specification contains two frame formats known as **Extended Frame** and **Standard Frame** which contain 29-bit IDs and 11-bit IDs respectively. A CAN message consists of the following components - 29-bit or 11-bit ID - Data Length Code (DLC) between 0 to 8 @@ -71,26 +56,13 @@ A CAN message consists of the following components Error States and Counters ^^^^^^^^^^^^^^^^^^^^^^^^^ -The CAN2.0B specification implements fault confinement by requiring every CAN node -to maintain two internal error counters known as the **Transmit Error Counter (TEC)** -and the **Receive Error Counter (REC)**. The two error counters are used to determine -a CAN node's **error state**, and the counters are incremented and decremented -following a set of rules (see CAN2.0B specification). These error states are known -as **Error Active**, **Error Passive**, and **Bus-Off**. +The CAN2.0B specification implements fault confinement by requiring every CAN node to maintain two internal error counters known as the **Transmit Error Counter (TEC)** and the **Receive Error Counter (REC)**. The two error counters are used to determine a CAN node's **error state**, and the counters are incremented and decremented following a set of rules (see CAN2.0B specification). These error states are known as **Error Active**, **Error Passive**, and **Bus-Off**. -**Error Active:** A CAN node is Error Active when **both TEC and REC are less -than 128** and indicates a CAN node is operating normally. Error Active nodes are -allowed to participate in CAN bus activities, and will actively signal any error -conditions it detects by transmitting an **Active Error Flag** over the CAN bus. +**Error Active:** A CAN node is Error Active when **both TEC and REC are less than 128** and indicates a CAN node is operating normally. Error Active nodes are allowed to participate in CAN bus activities, and will actively signal any error conditions it detects by transmitting an **Active Error Flag** over the CAN bus. -**Error Passive:** A CAN node is Error Passive when **either the TEC or REC becomes -greater than or equal to 128**. Error Passive nodes are still able to take part in -CAN bus activities, but will instead transmit a **Passive Error Flag** upon -detection of an error. +**Error Passive:** A CAN node is Error Passive when **either the TEC or REC becomes greater than or equal to 128**. Error Passive nodes are still able to take part in CAN bus activities, but will instead transmit a **Passive Error Flag** upon detection of an error. -**Bus-Off:** A CAN node becomes Bus-Off when the **TEC becomes greater than or equal -to 256**. A Bus-Off node is unable take part in CAN bus activity and will remain so -until it undergoes bus recovery. +**Bus-Off:** A CAN node becomes Bus-Off when the **TEC becomes greater than or equal to 256**. A Bus-Off node is unable take part in CAN bus activity and will remain so until it undergoes bus recovery. .. ---------------------- Signal Lines and Transceiver ------------------------- @@ -100,35 +72,22 @@ until it undergoes bus recovery. Signals Lines and Transceiver ----------------------------- -The CAN controller does not contain a internal transceiver and therefore -**requires an external transceiver** to operate. The type of external transceiver will -depend on the application's physical layer specification (e.g. using SN65HVD23X -transceivers for ISO 11898-2 compatibility). +The CAN controller does not contain a internal transceiver and therefore **requires an external transceiver** to operate. The type of external transceiver will depend on the application's physical layer specification (e.g. using SN65HVD23X transceivers for ISO 11898-2 compatibility). -The CAN controller's interface consists of 4 signal lines known as **TX, RX, BUS-OFF, -and CLKOUT**. These four signal lines can be routed through the GPIO Matrix to GPIOs. +The CAN controller's interface consists of 4 signal lines known as **TX, RX, BUS-OFF, and CLKOUT**. These four signal lines can be routed through the GPIO Matrix to GPIOs. .. blockdiag:: ../../../_static/diagrams/can/can_controller_signals.diag :caption: Signal lines of the CAN controller :align: center -**TX and RX:** The TX and RX signal lines are required to interface with an -external CAN transceiver. Both signal lines represent/interpret a dominant bit -as a low logic level (0V), and a recessive bit as a high logic level (3.3V). +**TX and RX:** The TX and RX signal lines are required to interface with an external CAN transceiver. Both signal lines represent/interpret a dominant bit as a low logic level (0V), and a recessive bit as a high logic level (3.3V). -**BUS-OFF:** The BUS-OFF signal line is **optional** and is set to a low logic level -(0V) whenever the CAN controller reaches a bus-off state. The BUS-OFF signal line -is set to a high logic level (3.3V) otherwise. +**BUS-OFF:** The BUS-OFF signal line is **optional** and is set to a low logic level (0V) whenever the CAN controller reaches a bus-off state. The BUS-OFF signal line is set to a high logic level (3.3V) otherwise. -**CLKOUT:** The CLKOUT signal line is **optional** and outputs a prescaled version -of the CAN controller's source clock (APB Clock). +**CLKOUT:** The CLKOUT signal line is **optional** and outputs a prescaled version of the CAN controller's source clock (APB Clock). .. note:: - An external transceiver **must internally tie the TX input and the RX output** - such that a change in logic level to the TX signal line can be observed on the - RX line. Failing to do so will cause the CAN controller to interpret differences - in logic levels between the two signal lines as a lost in arbitration or a - bit error. + An external transceiver **must internally tie the TX input and the RX output** such that a change in logic level to the TX signal line can be observed on the RX line. Failing to do so will cause the CAN controller to interpret differences in logic levels between the two signal lines as a lost in arbitration or a bit error. .. ------------------------------ Configuration -------------------------------- @@ -143,111 +102,86 @@ Operating Modes The CAN driver supports the following modes of operations: -**Normal Mode:** The normal operating mode allows the CAN controller to take part -in bus activities such as transmitting and receiving messages/error frames. -Acknowledgement from another CAN node is required when transmitting message frames. +**Normal Mode:** The normal operating mode allows the CAN controller to take part in bus activities such as transmitting and receiving messages/error frames. Acknowledgement from another CAN node is required when transmitting message frames. -**No Ack Mode:** The No Acknowledgement mode is similar to normal mode, however -acknowledgements are not required when transmitting message frames. This mode is -useful when self testing the CAN controller. +**No Ack Mode:** The No Acknowledgement mode is similar to normal mode, however acknowledgements are not required when transmitting message frames. This mode is useful when self testing the CAN controller. -**Listen Only Mode:** This mode will prevent the CAN controller from taking part -in bus activities. Therefore transmissions of messages/acknowledgement/error frames -will be disabled. However the the CAN controller will still be able to receive -messages (without acknowledging). This mode is suited for applications such as -CAN bus monitoring. +**Listen Only Mode:** This mode will prevent the CAN controller from taking part in bus activities. Therefore transmissions of messages/acknowledgement/error frames will be disabled. However the the CAN controller will still be able to receive messages (without acknowledging). This mode is suited for applications such as CAN bus monitoring. Alerts ^^^^^^ -The CAN driver contains an alert feature which is used to notify the application -level of certain CAN driver events. Alerts are selectively enabled when the -CAN driver is installed, but can be reconfigured during runtime by calling -:cpp:func:`can_reconfigure_alerts`. The application can then wait for any enabled -alerts to occur by calling :cpp:func:`can_read_alerts`. The CAN driver supports -the following alerts: +The CAN driver contains an alert feature which is used to notify the application level of certain CAN driver events. Alerts are selectively enabled when the CAN driver is installed, but can be reconfigured during runtime by calling :cpp:func:`can_reconfigure_alerts`. The application can then wait for any enabled alerts to occur by calling :cpp:func:`can_read_alerts`. The CAN driver supports the following alerts: -+------------------------------------+------------------------------------------------------------------------+ -| Alert | Description | -+====================================+=============================================+==========================+ -| ``CAN_ALERT_TX_IDLE`` | No more messages queued for transmission | -+------------------------------------+------------------------------------------------------------------------+ -| ``CAN_ALERT_TX_SUCCESS`` | The previous transmission was successful | -+------------------------------------+------------------------------------------------------------------------+ -| ``CAN_ALERT_BELOW_ERR_WARN`` | Both error counters have dropped below error warning limit | -+------------------------------------+------------------------------------------------------------------------+ -| ``CAN_ALERT_ERR_ACTIVE`` | CAN controller has become error active | -+------------------------------------+------------------------------------------------------------------------+ -| ``CAN_ALERT_RECOVERY_IN_PROGRESS`` | CAN controller is undergoing bus recovery | -+------------------------------------+------------------------------------------------------------------------+ -| ``CAN_ALERT_BUS_RECOVERED`` | CAN controller has successfully completed bus recovery | -+------------------------------------+------------------------------------------------------------------------+ -| ``CAN_ALERT_ARB_LOST`` | The previous transmission lost arbitration | -+------------------------------------+------------------------------------------------------------------------+ -| ``CAN_ALERT_ABOVE_ERR_WARN`` | One of the error counters have exceeded the error warning limit | -+------------------------------------+------------------------------------------------------------------------+ -| ``CAN_ALERT_BUS_ERROR`` | A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus | -+------------------------------------+------------------------------------------------------------------------+ -| ``CAN_ALERT_TX_FAILED`` | The previous transmission has failed | -+------------------------------------+------------------------------------------------------------------------+ -| ``CAN_ALERT_RX_QUEUE_FULL`` | The RX queue is full causing a received frame to be lost | -+------------------------------------+------------------------------------------------------------------------+ -| ``CAN_ALERT_ERR_PASS`` | CAN controller has become error passive | -+------------------------------------+------------------------------------------------------------------------+ -| ``CAN_ALERT_BUS_OFF`` | Bus-off condition occurred. CAN controller can no longer influence bus | -+------------------------------------+------------------------------------------------------------------------+ ++------------------------------------+-----------------------------------------+ +| Alert | Description | ++====================================+=========================================+ +| ``CAN_ALERT_TX_IDLE`` | No more messages queued for | +| | transmission | ++------------------------------------+-----------------------------------------+ +| ``CAN_ALERT_TX_SUCCESS`` | The previous transmission was | +| | successful | ++------------------------------------+-----------------------------------------+ +| ``CAN_ALERT_BELOW_ERR_WARN`` | Both error counters have dropped below | +| | error warning limit | ++------------------------------------+-----------------------------------------+ +| ``CAN_ALERT_ERR_ACTIVE`` | CAN controller has become error active | ++------------------------------------+-----------------------------------------+ +| ``CAN_ALERT_RECOVERY_IN_PROGRESS`` | CAN controller is undergoing bus | +| | recovery | ++------------------------------------+-----------------------------------------+ +| ``CAN_ALERT_BUS_RECOVERED`` | CAN controller has successfully | +| | completed bus recovery | ++------------------------------------+-----------------------------------------+ +| ``CAN_ALERT_ARB_LOST`` | The previous transmission lost | +| | arbitration | ++------------------------------------+-----------------------------------------+ +| ``CAN_ALERT_ABOVE_ERR_WARN`` | One of the error counters have exceeded | +| | the error warning limit | ++------------------------------------+-----------------------------------------+ +| ``CAN_ALERT_BUS_ERROR`` | A (Bit, Stuff, CRC, Form, ACK) error | +| | has occurred on the bus | ++------------------------------------+-----------------------------------------+ +| ``CAN_ALERT_TX_FAILED`` | The previous transmission has failed | ++------------------------------------+-----------------------------------------+ +| ``CAN_ALERT_RX_QUEUE_FULL`` | The RX queue is full causing a received | +| | frame to be lost | ++------------------------------------+-----------------------------------------+ +| ``CAN_ALERT_ERR_PASS`` | CAN controller has become error passive | ++------------------------------------+-----------------------------------------+ +| ``CAN_ALERT_BUS_OFF`` | Bus-off condition occurred. CAN | +| | controller can no longer influence bus | ++------------------------------------+-----------------------------------------+ .. note:: - The **error warning limit** can be used to preemptively warn the application - of bus errors before the error passive state is reached. By default the CAN - driver sets the **error warning limit** to **96**. The ``CAN_ALERT_ABOVE_ERR_WARN`` - is raised when the TEC or REC becomes larger then or equal to the error warning - limit. The ``CAN_ALERT_BELOW_ERR_WARN`` is raised when both TEC and REC return - back to values below **96**. + The **error warning limit** can be used to preemptively warn the application of bus errors before the error passive state is reached. By default the CAN driver sets the **error warning limit** to **96**. The ``CAN_ALERT_ABOVE_ERR_WARN`` is raised when the TEC or REC becomes larger then or equal to the error warning limit. The ``CAN_ALERT_BELOW_ERR_WARN`` is raised when both TEC and REC return back to values below **96**. .. note:: - When enabling alerts, the ``CAN_ALERT_AND_LOG`` flag can be used to cause the - CAN driver to log any raised alerts to UART. The ``CAN_ALERT_ALL`` and - ``CAN_ALERT_NONE`` macros can also be used to enable/disable all alerts during - configuration/reconfiguration. + When enabling alerts, the ``CAN_ALERT_AND_LOG`` flag can be used to cause the CAN driver to log any raised alerts to UART. The ``CAN_ALERT_ALL`` and ``CAN_ALERT_NONE`` macros can also be used to enable/disable all alerts during configuration/reconfiguration. Bit Timing ^^^^^^^^^^ -The operating bit rate of the CAN controller is configured using the -:cpp:type:`can_timing_config_t` structure. The period of each bit is made up of -multiple **time quanta**, and the period of a **time quanta** is determined by a -prescaled version of the CAN controller's source clock. A single bit contains the -following segments in the following order: +The operating bit rate of the CAN controller is configured using the :cpp:type:`can_timing_config_t` structure. The period of each bit is made up of multiple **time quanta**, and the period of a **time quanta** is determined by a prescaled version of the CAN controller's source clock. A single bit contains the following segments in the following order: 1. The **Synchronization Segment** consists of a single time quanta 2. **Timing Segment 1** consists of 1 to 16 time quanta before sample point 3. **Timing Segment 2** consists of 1 to 8 time quanta after sample point -The **Baudrate Prescaler** is used to determine the period of each time quanta by -dividing the CAN controller's source clock (80 MHz APB clock). The ``brp`` can be -**any even number from 2 to 128**. +The **Baudrate Prescaler** is used to determine the period of each time quanta by dividing the CAN controller's source clock (80 MHz APB clock). The ``brp`` can be **any even number from 2 to 128**. .. packetdiag:: ../../../_static/diagrams/can/can_bit_timing.diag :caption: Bit timing configuration for 500kbit/s given BRP = 8 :align: center -The sample point of a bit is located on the intersection of Timing Segment 1 and -2. Enabling **Triple Sampling** will cause 3 time quanta to be sampled per bit -instead of 1 (extra samples are located at the tail end of Timing Segment 1). +The sample point of a bit is located on the intersection of Timing Segment 1 and 2. Enabling **Triple Sampling** will cause 3 time quanta to be sampled per bit instead of 1 (extra samples are located at the tail end of Timing Segment 1). -The **Synchronization Jump Width** is used to determined the maximum number of -time quanta a single bit time can be lengthened/shortened for synchronization -purposes. ``sjw`` can **range from 1 to 4**. +The **Synchronization Jump Width** is used to determined the maximum number of time quanta a single bit time can be lengthened/shortened for synchronization purposes. ``sjw`` can **range from 1 to 4**. .. note:: - Multiple combinations of ``brp``, ``tseg_1``, ``tseg_2``, and ``sjw`` can - achieve the same bit rate. Users should tune these values to the physical - characteristics of their CAN bus by taking into account factors such as - **propagation delay, node information processing time, and phase errors**. + Multiple combinations of ``brp``, ``tseg_1``, ``tseg_2``, and ``sjw`` can achieve the same bit rate. Users should tune these values to the physical characteristics of their CAN bus by taking into account factors such as **propagation delay, node information processing time, and phase errors**. -Bit timing **macro initializers** are also available for commonly used CAN bus bit rates. -The following macro initiliazers are provided by the CAN driver. +Bit timing **macro initializers** are also available for commonly used CAN bus bit rates. The following macro initializers are provided by the CAN driver. - ``CAN_TIMING_CONFIG_25KBITS()`` - ``CAN_TIMING_CONFIG_50KBITS()`` @@ -261,36 +195,17 @@ The following macro initiliazers are provided by the CAN driver. Acceptance Filter ^^^^^^^^^^^^^^^^^ -The CAN controller contains a hardware acceptance filter which can be used to -filter CAN messages of a particular ID. A node that filters out a message -**will not receive the message, but will still acknowledge it**. Acceptances -filters can make a node more efficient by filtering out messages sent over the -CAN bus that are irrelevant to the CAN node in question. The CAN controller's -acceptance filter is configured using two 32-bit values within :cpp:type:`can_filter_config_t` -known as the **acceptance code** and the **acceptance mask**. +The CAN controller contains a hardware acceptance filter which can be used to filter CAN messages of a particular ID. A node that filters out a message **will not receive the message, but will still acknowledge it**. Acceptances filters can make a node more efficient by filtering out messages sent over the CAN bus that are irrelevant to the CAN node in question. The CAN controller's acceptance filter is configured using two 32-bit values within :cpp:type:`can_filter_config_t` known as the **acceptance code** and the **acceptance mask**. -The **acceptance code** specifies the bit sequence which a message's ID, RTR, and -data bytes must match in order for the message to be received by the CAN -controller. The **acceptance mask** is a bit sequence specifying which bits of -the acceptance code can be ignored. This allows for a messages of different IDs -to be accepted by a single acceptance code. +The **acceptance code** specifies the bit sequence which a message's ID, RTR, and data bytes must match in order for the message to be received by the CAN controller. The **acceptance mask** is a bit sequence specifying which bits of the acceptance code can be ignored. This allows for a messages of different IDs to be accepted by a single acceptance code. -The acceptance filter can be used under **Single or Dual Filter Mode**. -Single Filter Mode will use the acceptance code and mask to define a single -filter. This allows for the first two data bytes of a standard frame to be filtered, -or the entirety of an extended frame's 29-bit ID. The following diagram illustrates -how the 32-bit acceptance code and mask will be interpreted under Single Filter Mode -(Note: The yellow and blue fields represent standard and extended CAN frames respectively). +The acceptance filter can be used under **Single or Dual Filter Mode**. Single Filter Mode will use the acceptance code and mask to define a single filter. This allows for the first two data bytes of a standard frame to be filtered, or the entirety of an extended frame's 29-bit ID. The following diagram illustrates how the 32-bit acceptance code and mask will be interpreted under Single Filter Mode (Note: The yellow and blue fields represent standard and extended CAN frames respectively). .. packetdiag:: ../../../_static/diagrams/can/can_acceptance_filter_single.diag :caption: Bit layout of single filter mode (Right side MSBit) :align: center -**Dual Filter Mode** will use the acceptance code and mask to define two separate -filters allowing for increased flexibility of ID's to accept, but does not allow -for all 29-bits of an extended ID to be filtered. The following diagram illustrates -how the 32-bit acceptance code and mask will be interpreted under **Dual Filter Mode** -(Note: The yellow and blue fields represent standard and extended CAN frames respectively). +**Dual Filter Mode** will use the acceptance code and mask to define two separate filters allowing for increased flexibility of ID's to accept, but does not allow for all 29-bits of an extended ID to be filtered. The following diagram illustrates how the 32-bit acceptance code and mask will be interpreted under **Dual Filter Mode** (Note: The yellow and blue fields represent standard and extended CAN frames respectively). .. packetdiag:: ../../../_static/diagrams/can/can_acceptance_filter_dual.diag :caption: Bit layout of dual filter mode (Right side MSBit) @@ -299,10 +214,7 @@ how the 32-bit acceptance code and mask will be interpreted under **Dual Filter Disabling TX Queue ^^^^^^^^^^^^^^^^^^ -The TX queue can be disabled during configuration by setting the ``tx_queue_len`` -member of :cpp:type:`can_general_config_t` to ``0``. This will allow applications -that do not require message transmission to save a small amount of memory when -using the CAN driver. +The TX queue can be disabled during configuration by setting the ``tx_queue_len`` member of :cpp:type:`can_general_config_t` to ``0``. This will allow applications that do not require message transmission to save a small amount of memory when using the CAN driver. .. -------------------------------- CAN Driver --------------------------------- @@ -312,86 +224,70 @@ using the CAN driver. Driver Operation ---------------- -The CAN driver is designed with distinct states and strict rules regarding the -functions or conditions that trigger a state transition. The following diagram -illustrates the various states and their transitions. +The CAN driver is designed with distinct states and strict rules regarding the functions or conditions that trigger a state transition. The following diagram illustrates the various states and their transitions. .. blockdiag:: ../../../_static/diagrams/can/can_state_transition.diag :caption: State transition diagram of the CAN driver (see table below) :align: center +-------+------------------------+------------------------------------+ -| Label | Transition | Action/Condition | +| Label | Transition | Action/Condition | +=======+========================+====================================+ -| A | Uninstalled -> Stopped | :cpp:func:`can_driver_install` | +| A | Uninstalled -> Stopped | :cpp:func:`can_driver_install` | +-------+------------------------+------------------------------------+ -| B | Stopped -> Uninstalled | :cpp:func:`can_driver_uninstall` | +| B | Stopped -> Uninstalled | :cpp:func:`can_driver_uninstall` | +-------+------------------------+------------------------------------+ -| C | Stopped -> Running | :cpp:func:`can_start` | +| C | Stopped -> Running | :cpp:func:`can_start` | +-------+------------------------+------------------------------------+ -| D | Running -> Stopped | :cpp:func:`can_stop` | +| D | Running -> Stopped | :cpp:func:`can_stop` | +-------+------------------------+------------------------------------+ -| E | Running -> Bus-Off | Transmit Error Counter >= 256 | +| E | Running -> Bus-Off | Transmit Error Counter >= 256 | +-------+------------------------+------------------------------------+ -| F | Bus-Off -> Uninstalled | :cpp:func:`can_driver_uninstall` | +| F | Bus-Off -> Uninstalled | :cpp:func:`can_driver_uninstall` | +-------+------------------------+------------------------------------+ -| G | Bus-Off -> Recovering | :cpp:func:`can_initiate_recovery` | +| G | Bus-Off -> Recovering | :cpp:func:`can_initiate_recovery` | +-------+------------------------+------------------------------------+ -| H | Recovering -> Stopped | 128 occurrences of bus-free signal | +| H | Recovering -> Stopped | 128 occurrences of bus-free signal | +-------+------------------------+------------------------------------+ Driver States ^^^^^^^^^^^^^ -**Uninstalled**: In the uninstalled state, no memory is allocated for the driver -and the CAN controller is powered OFF. +**Uninstalled**: In the uninstalled state, no memory is allocated for the driver and the CAN controller is powered OFF. -**Stopped**: In this state, the CAN controller is powered ON and the CAN driver -has been installed. However the CAN controller will be unable to take part in -any CAN bus activities such as transmitting, receiving, or acknowledging messages. +**Stopped**: In this state, the CAN controller is powered ON and the CAN driver has been installed. However the CAN controller will be unable to take part in any CAN bus activities such as transmitting, receiving, or acknowledging messages. -**Running**: In the running state, the CAN controller is able to take part in -bus activities. Therefore messages can be transmitted/received/acknowledged. -Furthermore the CAN controller will be able to transmit error frames upon detection -of errors on the CAN bus. +**Running**: In the running state, the CAN controller is able to take part in bus activities. Therefore messages can be transmitted/received/acknowledged. Furthermore the CAN controller will be able to transmit error frames upon detection of errors on the CAN bus. -**Bus-Off**: The bus-off state is automatically entered when the CAN controller's -Transmit Error Counter becomes greater than or equal to 256 (see CAN2.0B specification -regarding error counter rules). The bus-off state indicates the occurrence of severe -errors on the CAN bus or in the CAN controller. Whilst in the bus-off state, the -CAN controller will be unable to take part in any CAN bus activities. To exit -the bus-off state, the CAN controller must undergo the bus recovery process. +**Bus-Off**: The bus-off state is automatically entered when the CAN controller's Transmit Error Counter becomes greater than or equal to 256 (see CAN2.0B specification regarding error counter rules). The bus-off state indicates the occurrence of severe errors on the CAN bus or in the CAN controller. Whilst in the bus-off state, the CAN controller will be unable to take part in any CAN bus activities. To exit the bus-off state, the CAN controller must undergo the bus recovery process. -**Recovering**: The recovering state is entered when the CAN driver undergoes -bus recovery. The CAN driver/controller will remain in the recovering state until -the 128 occurrences of the bus-free signal (see CAN2.0B specification) is observed -on the CAN bus. +**Recovering**: The recovering state is entered when the CAN driver undergoes bus recovery. The CAN driver/controller will remain in the recovering state until the 128 occurrences of the bus-free signal (see CAN2.0B specification) is observed on the CAN bus. Message Flags ^^^^^^^^^^^^^ -The CAN driver distinguishes different types of CAN messages by using the message -flags in the ``flags`` field of :cpp:type:`can_message_t`. These flags help -distinguish whether a message is in standard or extended format, an RTR, and the -type of transmission to use when transmitting such a message. The CAN driver -supports the following flags: +The CAN driver distinguishes different types of CAN messages by using the message flags in the ``flags`` field of :cpp:type:`can_message_t`. These flags help distinguish whether a message is in standard or extended format, an RTR, and the type of transmission to use when transmitting such a message. The CAN driver supports the following flags: -+-------------------------------+---------------------------------------------------------------+ -| Flag | Description | -+===============================+===============================================================+ -| ``CAN_MSG_FLAG_EXTD`` | Message is in Extended Frame Format (29bit ID) | -+-------------------------------+---------------------------------------------------------------+ -| ``CAN_MSG_FLAG_RTR`` | Message is a Remote Transmit Request | -+-------------------------------+---------------------------------------------------------------+ -| ``CAN_MSG_FLAG_SS`` | Transmit message using Single Shot Transmission (Message will | -| | note be retransmitted upon error or loss of arbitration) | -+-------------------------------+---------------------------------------------------------------+ -| ``CAN_MSG_FLAG_SELF`` | Transmit message using Self Reception Request (Transmitted | -| | message will also received by the same node) | -+-------------------------------+---------------------------------------------------------------+ -| ``CAN_MSG_FLAG_DLC_NON_COMP`` | Message's Data length code is larger than 8. This | -| | will break compliance with CAN2.0B | -+-------------------------------+---------------------------------------------------------------+ ++-------------------------------+----------------------------------------------+ +| Flag | Description | ++===============================+==============================================+ +| ``CAN_MSG_FLAG_EXTD`` | Message is in Extended Frame Format | +| | (29bit ID) | ++-------------------------------+----------------------------------------------+ +| ``CAN_MSG_FLAG_RTR`` | Message is a Remote Transmit Request | ++-------------------------------+----------------------------------------------+ +| ``CAN_MSG_FLAG_SS`` | Transmit message using Single Shot | +| | Transmission (Message will not be | +| | retransmitted upon error or loss of | +| | arbitration) | ++-------------------------------+----------------------------------------------+ +| ``CAN_MSG_FLAG_SELF`` | Transmit message using Self Reception | +| | Request (Transmitted message will also | +| | received by the same node) | ++-------------------------------+----------------------------------------------+ +| ``CAN_MSG_FLAG_DLC_NON_COMP`` | Message's Data length code is larger than 8. | +| | This will break compliance with CAN2.0B | ++-------------------------------+----------------------------------------------+ .. note:: The ``CAN_MSG_FLAG_NONE`` flag can be used for Standard Frame Format messages @@ -407,9 +303,7 @@ Examples Configuration & Installation ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -The following code snippet demonstrates how to configure, install, and start the -CAN driver via the use of the various configuration structures, macro initializers, -the :cpp:func:`can_driver_install` function, and the :cpp:func:`can_start` function. +The following code snippet demonstrates how to configure, install, and start the CAN driver via the use of the various configuration structures, macro initializers, the :cpp:func:`can_driver_install` function, and the :cpp:func:`can_start` function. .. code-block:: c @@ -443,14 +337,12 @@ the :cpp:func:`can_driver_install` function, and the :cpp:func:`can_start` funct } -The usage of macro initializers are not mandatory and each of the configuration -structures can be manually. +The usage of macro initializers are not mandatory and each of the configuration structures can be manually. Message Transmission ^^^^^^^^^^^^^^^^^^^^ -The following code snippet demonstrates how to transmit a message via the usage -of the :cpp:type:`can_message_t` type and :cpp:func:`can_transmit` function. +The following code snippet demonstrates how to transmit a message via the usage of the :cpp:type:`can_message_t` type and :cpp:func:`can_transmit` function. .. code-block:: c @@ -477,8 +369,7 @@ of the :cpp:type:`can_message_t` type and :cpp:func:`can_transmit` function. Message Reception ^^^^^^^^^^^^^^^^^ -The following code snippet demonstrates how to receive a message via the usage -of the :cpp:type:`can_message_t` type and :cpp:func:`can_receive` function. +The following code snippet demonstrates how to receive a message via the usage of the :cpp:type:`can_message_t` type and :cpp:func:`can_receive` function. .. code-block:: c @@ -511,9 +402,7 @@ of the :cpp:type:`can_message_t` type and :cpp:func:`can_receive` function. Reconfiguring and Reading Alerts ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -The following code snippet demonstrates how to reconfigure and read CAN driver -alerts via the use of the :cpp:func:`can_reconfigure_alerts` and -:cpp:func:`can_read_alerts` functions. +The following code snippet demonstrates how to reconfigure and read CAN driver alerts via the use of the :cpp:func:`can_reconfigure_alerts` and :cpp:func:`can_read_alerts` functions. .. code-block:: c @@ -536,8 +425,7 @@ alerts via the use of the :cpp:func:`can_reconfigure_alerts` and Stop and Uninstall ^^^^^^^^^^^^^^^^^^ -The following code demonstrates how to stop and uninstall the CAN driver via the -use of the :cpp:func:`can_stop` and :cpp:func:`can_driver_uninstall` functions. +The following code demonstrates how to stop and uninstall the CAN driver via the use of the :cpp:func:`can_stop` and :cpp:func:`can_driver_uninstall` functions. .. code-block:: c @@ -564,13 +452,9 @@ use of the :cpp:func:`can_stop` and :cpp:func:`can_driver_uninstall` functions. Multiple ID Filter Configuration ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -The acceptance mask in :cpp:type:`can_filter_config_t` can be configured such that -two or more IDs will be accepted for a single filter. For a particular filter to -accept multiple IDs, the conflicting bit positions amongst the IDs must be set -in the acceptance mask. The acceptance code can be set to any one of the IDs. +The acceptance mask in :cpp:type:`can_filter_config_t` can be configured such that two or more IDs will be accepted for a single filter. For a particular filter to accept multiple IDs, the conflicting bit positions amongst the IDs must be set in the acceptance mask. The acceptance code can be set to any one of the IDs. -The following example shows how the calculate the acceptance mask given multiple -IDs:: +The following example shows how the calculate the acceptance mask given multiple IDs:: ID1 = 11'b101 1010 0000 ID2 = 11'b101 1010 0001 @@ -582,22 +466,11 @@ IDs:: Application Examples ^^^^^^^^^^^^^^^^^^^^ -**Network Example:** The CAN Network example demonstrates communication between -two ESP32s using the CAN driver API. One CAN node acts as a network master initiate -and ceasing the transfer of a data from another CAN node acting as a network slave. -The example can be found via :example:`peripherals/can/can_network`. +**Network Example:** The CAN Network example demonstrates communication between two ESP32s using the CAN driver API. One CAN node acts as a network master initiate and ceasing the transfer of a data from another CAN node acting as a network slave. The example can be found via :example:`peripherals/can/can_network`. -**Alert and Recovery Example:** This example demonstrates how to use the CAN driver's -alert and bus recovery API. The example purposely introduces errors on the CAN -bus to put the CAN controller into the Bus-Off state. An alert is used to detect -the Bus-Off state and trigger the bus recovery process. The example can be found -via :example:`peripherals/can/can_alert_and_recovery`. +**Alert and Recovery Example:** This example demonstrates how to use the CAN driver's alert and bus recovery API. The example purposely introduces errors on the CAN bus to put the CAN controller into the Bus-Off state. An alert is used to detect the Bus-Off state and trigger the bus recovery process. The example can be found via :example:`peripherals/can/can_alert_and_recovery`. -**Self Test Example:** This example uses the No Acknowledge Mode and Self Reception -Request to cause the CAN controller to send and simultaneously receive a series -of messages. This example can be used to verify if the connections between the CAN -controller and the external transceiver are working correctly. The example can be -found via :example:`peripherals/can/can_self_test`. +**Self Test Example:** This example uses the No Acknowledge Mode and Self Reception Request to cause the CAN controller to send and simultaneously receive a series of messages. This example can be used to verify if the connections between the CAN controller and the external transceiver are working correctly. The example can be found via :example:`peripherals/can/can_self_test`. .. ---------------------------- API Reference ---------------------------------- diff --git a/examples/peripherals/can/can_network/can_network_master/main/can_network_example_master_main.c b/examples/peripherals/can/can_network/can_network_master/main/can_network_example_master_main.c index 6e98a3403..7372e7f77 100644 --- a/examples/peripherals/can/can_network/can_network_master/main/can_network_example_master_main.c +++ b/examples/peripherals/can/can_network/can_network_master/main/can_network_example_master_main.c @@ -131,7 +131,8 @@ static void can_receive_task(void *arg) vTaskDelete(NULL); } -static void can_transmit_task(void *arg) { +static void can_transmit_task(void *arg) +{ while (1) { tx_task_action_t action; xQueueReceive(tx_task_queue, &action, portMAX_DELAY); @@ -158,7 +159,8 @@ static void can_transmit_task(void *arg) { vTaskDelete(NULL); } -void can_control_task(void *arg) { +static void can_control_task(void *arg) +{ xSemaphoreTake(ctrl_task_sem, portMAX_DELAY); tx_task_action_t tx_action; rx_task_action_t rx_action;