/*
- * Copyright (C) 2012-2013 Czech Technical University in Prague
+ * Copyright (C) 2012-2014, 2016 Czech Technical University in Prague
*
* Created on: 28.2.2013
*
* Authors:
* - Michal Horn
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ * This document contains proprietary information belonging to Czech
+ * Technical University in Prague. Passing on and copying of this
+ * document, and communication of its contents is not permitted
+ * without prior written authorization.
*
* File : cmd_can.c
*
* Abstract:
- * This file contains commands for CAN test
+ * This file contains commands for CAN test
*
*/
#include "sys/sys.h"
#include <stdio.h>
-/** Semaphore used for blocking task until message is received */
-extern xSemaphoreHandle canMsgReceived;
-/** Semaphore used for blocking task until message is sent */
-extern xSemaphoreHandle canMsgSent;
-/** Pointer to Destination CAN registers */
-extern canBASE_t* canDst;
-/** Pointer to Source CAN registers */
-extern canBASE_t* canSrc;
-/** Can message box for received messages */
-extern uint32_t canMsgBox;
-/** Error counter for errors in sending */
-extern uint32_t canSendError;
-/** Error counter for errors in receiving */
-extern uint32_t canRecError;
-
-static void canPrintStatus(int can_num, uint32_t es)
-{
- uint32_t errorLevel = es & 0xE0U;
- char* levText;
-
- switch (errorLevel) {
- case canLEVEL_BUS_OFF:
- levText = "Bus-Off";
- break;
- case canLEVEL_PASSIVE:
- levText = "Error Passive";
- break;
- case canLEVEL_WARNING:
- levText = "Warning";
- break;
- case canLEVEL_ACTIVE:
- levText = "Bus-On";
- break;
- default:
- levText = "Unknown";
- }
-
- rpp_sci_printf("CAN%d status: %s, ES: %#x\n", can_num, levText, es);
-}
-
-uint32_t canCheckForError(int can_num, uint32_t es)
-{
- uint32_t errorLevel = es & 0xE0U;
-
- if (errorLevel != 0) {
- canPrintStatus(can_num, es);
- }
-
- return errorLevel;
-}
-
-/**
- * @brief Command for external CAN loopback testing.
- *
- * @param[in] cmd_io Pointer to IO stack
- * @param[in] des Pointer to command descriptor
- * @param[in] param Parameters of command
- * @return 0 when OK or error code
+/*
+ * Error codes definitions for RPP CAN functions tests.
*/
-int cmd_do_test_can_loopback(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
-{
- uint32_t can_src, can_dst;
- canBASE_t *canBases[3] = {canREG1, canREG2, canREG3};
- uint32_t canMailBoxes[3] = {canMESSAGE_BOX1, canMESSAGE_BOX2, canMESSAGE_BOX3};
- uint32_t txTimeOutCnt = 0;
- uint32_t rxTimeOutCnt = 0;
- uint32_t messagesTransmitted = 0;
- uint32_t messagesReceived = 0;
- uint32_t i;
- uint8_t tx_data[8] = {'T', 'E', 'S', 'T', ' ', 'C', 'A', 'N'};
- uint8_t rx_data[8] = {0, 0, 0, 0, 0, 0, 0, 0 };
- char *p=param[1];
- char spareParams;
-
-
- dmmREG->PC4 = (1<<(13)); // set CAN_NSTB
- vTaskDelay(50/portTICK_RATE_MS);
- dmmREG->PC5 = (1<<(15)); // clr CAN_EN
- vTaskDelay(50/portTICK_RATE_MS);
- dmmREG->PC5 = (1<<(13)); // clr CAN_NSTB
- vTaskDelay(50/portTICK_RATE_MS);
- dmmREG->PC4 = (1<<(13)); // set CAN_NSTB
- vTaskDelay(50/portTICK_RATE_MS);
- dmmREG->PC4 = (1<<(15)); // set CAN_EN
- vTaskDelay(50/portTICK_RATE_MS);
-
-
- if (sscanf(p, "%d %d %1s", &can_src, &can_dst, &spareParams) != 2) {
- return -CMDERR_BADPAR;
- }
-
- if (can_src == can_dst) {
- rpp_sci_printf("ERROR: Destination equals source!\n");
- return 1;
- }
- if (can_src < 1 | can_dst > 3) {
- rpp_sci_printf("Parameter out of range <1;3>!\n");
- return 1;
- }
- canSrc = canBases[can_src-1];
- canDst = canBases[can_dst-1];
- canMsgBox = canMailBoxes[can_src-1];
- canMsgReceived = xSemaphoreCreateCounting(1, 0);
- canMsgSent = xSemaphoreCreateCounting(1, 0);
-
- rpp_sci_printf("Testing CAN loopback\r\n");
- canREG1->CTL |= 1|(1<<9);
- canREG2->CTL |= 1|(1<<9);
- canREG3->CTL |= 1|(1<<9);
- canRecError = 0;
- canDst->CTL |= 1<<15; // Reset
- while (canDst->CTL & (1<<15)) ; // Wait for reset
- canSendError = 0;
- canSrc->CTL |= 1<<15;
- while (canSrc->CTL & (1<<15)) ;
- canInit();
- canDst->CTL |= 1<<9;
- canSrc->CTL |= 1<<9;
- vTaskDelay(50/portTICK_RATE_MS);
-
- i = canSrc->ES; // Reset error flag
- i = canDst->ES; // Reset error flag
- canEnableErrorNotification(canDst);
- canEnableErrorNotification(canSrc);
-
- for (i = 0; i < 100; i++) { // Send 100 times the message
- if (canCheckForError(can_src, canSendError) != canLEVEL_ACTIVE) {
- break;
- }
- canTransmit(canSrc, canMsgBox, tx_data);
- if (xSemaphoreTake(canMsgSent, 100/portTICK_RATE_MS) == pdFALSE) {
- txTimeOutCnt++;
- }
- else {
- if (canCheckForError(can_src, canSendError) & canLEVEL_BUS_OFF) {
- break;
- }
- else {
- messagesTransmitted++;
- if (xSemaphoreTake(canMsgReceived, 100/portTICK_RATE_MS) == pdFALSE) {
- rxTimeOutCnt++;
- }
- else {
- if (canGetData(canDst, canMsgBox, rx_data))
- messagesReceived++;
+#define ERR_CCT_HW_OBJ 0x0001 /**< Wrong HW object passed to the RPP CAN function. */
+#define ERR_CCT_MSG_MISMATCH 0x0010 /**< Received message does not match to the sent message. */
+#define ERR_CCT_RX_IND_NOT_CLEARED 0x0020 /**< Message received indicator was not cleared by the rpp_can_read function. */
+#define ERR_CCT_RX_IND_SET_NO_MSG_REC 0x0040 /**< Message received indicator is set, but no message could be retrieved by the rpp_can_read function. */
+#define ERR_CCT_RECV_TIMEOUT 0x0100 /**< Message receive timeout reached. */
+#define ERR_CCT_CLEAR_TX_PEND_TO 0x0200 /**< Timeout reached for waiting for the clearance of the transmission request flag. */
+#define ERR_CCT_SET_TX_PEND_TO 0x0400 /**< Timeout reached for waiting until the transmission request flag is set after the request is posted. */
+#define ERR_CCT_INIT 0x1000 /**< Error while initializing the CAN bus. */
+#define ERR_CCT_SEND 0x2000 /**< Error while sending a CAN message. */
+#define ERR_CCT_RCV 0x4000 /**< Error while receiving a CAN message */
+#define ERR_CCT_UNEXPECTED_RETVAL 0x0008 /**< Unexpected return value has been returned from some RPP CAN function. */
+
+#define CCT_TIMEOUT 100000 /**< Timeout for RPP CAN test steps. */
- if (canCheckForError(can_dst, canRecError) & canLEVEL_BUS_OFF) {
- break;
- }
- }
- }
- }
-
- rpp_sci_printf("Messages transmitted: %d/100\r\n", messagesTransmitted);
- rpp_sci_printf("Messages received: %d/100\r\n", messagesReceived);
- rpp_sci_printf("TX timeouts: %d\r\n", txTimeOutCnt);
- rpp_sci_printf("RX timeouts: %d\r\n", rxTimeOutCnt);
- rpp_sci_printf("Src TX error counter: %d\r\n", canSrc->EERC & 0xFFU);
- rpp_sci_printf("Src RX error counter: %d\r\n", (canSrc->EERC & 0xFF00U) >> 8);
- rpp_sci_printf("Dst TX error counter: %d\r\n", canDst->EERC & 0xFFU);
- rpp_sci_printf("Dst RX error counter: %d\r\n", (canDst->EERC & 0xFF00U) >> 8);
- canPrintStatus(can_src, canSendError);
- canPrintStatus(can_dst, canRecError);
-
- canDisableErrorNotification(canDst);
- canDisableErrorNotification(canSrc);
- vSemaphoreDelete(canMsgReceived);
- vSemaphoreDelete(canMsgSent);
- return 0;
- }
- return 0;
-}
+static int can_inited = 0;
+/* Default CAN timing set to 500kb */
+static struct rpp_can_timing_cfg can_timing[] = {
+ {
+ .brp = 10,
+ .phase_seg1 = 5,
+ .phase_seg2 = 2,
+ .prop_seg = 8,
+ .sjw = 1
+ },
+ {
+ .brp = 10,
+ .phase_seg1 = 5,
+ .phase_seg2 = 2,
+ .prop_seg = 8,
+ .sjw = 1
+ },
+ {
+ .brp = 10,
+ .phase_seg1 = 5,
+ .phase_seg2 = 2,
+ .prop_seg = 8,
+ .sjw = 1
+ },
+};
-static int can_inited = 0;
static struct rpp_can_ctrl_config ctrl_config[] = {
{
- .baudrate = 500000
+ .baudrate = 500000,
+ .clk = 80000000,
+ .timing_calc_method = RPP_CAN_TIMING_CALC_AUTO,
+ .timing_config = NULL
},
{
- .baudrate = 500000
+ .baudrate = 500000,
+ .clk = 80000000,
+ .timing_calc_method = RPP_CAN_TIMING_CALC_AUTO,
+ .timing_config = NULL
},
{
- .baudrate = 500000
+ .baudrate = 500000,
+ .clk = 80000000,
+ .timing_calc_method = RPP_CAN_TIMING_CALC_AUTO,
+ .timing_config = NULL
}
};
.type = RPP_CAN_MIXED,
.controller = 1,
.msg_obj = 1,
- .id = 1,
+ .id = 0,
.mask = 0,
},
{
.type = RPP_CAN_MIXED,
.controller = 2,
.msg_obj = 1,
- .id = 1,
+ .id = 0,
.mask = 0,
},
{
.type = RPP_CAN_MIXED,
.controller = 3,
.msg_obj = 1,
- .id = 1,
+ .id = 0,
.mask = 0,
}
};
-static struct rpp_can_config can_config = {
+struct rpp_can_config can_config = {
.num_tx_obj = 3,
.num_rx_obj = 3,
.tx_config = tx_config,
.ctrl = ctrl_config,
};
+/*
+ * Structures for RPP CAN functions tests.
+ */
-int cmd_do_can_init(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
+/**
+ * CAN test bit timings configurations.
+ */
+struct rpp_can_timing_cfg can_test_timing[] = {
+ {
+ .brp = 10,
+ .prop_seg = 8,
+ .phase_seg1 = 5,
+ .phase_seg2 = 2,
+ .sjw = 1
+ },
+ {
+ .brp = 10,
+ .prop_seg = 8,
+ .phase_seg1 = 5,
+ .phase_seg2 = 2,
+ .sjw = 1
+ },
+ {
+ .brp = 10,
+ .prop_seg = 8,
+ .phase_seg1 = 5,
+ .phase_seg2 = 2,
+ .sjw = 1
+ },
+};
+
+/**
+ * CAN test controllers configurations.
+ */
+struct rpp_can_ctrl_config can_test_ctrl_cfg[] = {
+ {
+ .baudrate = 500000,
+ .clk = 80000000,
+ .timing_calc_method = RPP_CAN_TIMING_CALC_MANUAL,
+ .timing_config = &can_test_timing[0]
+ },
+ {
+ .baudrate = 500000,
+ .clk = 80000000,
+ .timing_calc_method = RPP_CAN_TIMING_CALC_MANUAL,
+ .timing_config = &can_test_timing[1]
+ },
+ {
+ .baudrate = 500000,
+ .clk = 80000000,
+ .timing_calc_method = RPP_CAN_TIMING_CALC_MANUAL,
+ .timing_config = &can_test_timing[2]
+ },
+};
+
+/**
+ * CAN test TX configuration.
+ */
+struct rpp_can_tx_config can_test_tx_cfg[] = {
+ {
+ .type = RPP_CAN_STANDARD,
+ .controller = 1,
+ .msg_obj = 1
+ }
+};
+
+/**
+ * CAN test RX configuration.
+ */
+struct rpp_can_rx_config can_test_rx_cfg[] = {
+ {
+ .type = RPP_CAN_STANDARD,
+ .controller = 2,
+ .id = 0x1,
+ .mask = 1,
+ .msg_obj = 1
+ }
+};
+
+/**
+ * Root CAN test configuration structure
+ */
+struct rpp_can_config can_test_cfg = {
+ .num_tx_obj = 1,
+ .num_rx_obj = 1,
+ .tx_config = can_test_tx_cfg,
+ .rx_config = can_test_rx_cfg,
+ .ctrl = can_test_ctrl_cfg
+};
+
+/**
+ * Compare two CAN messages.
+ *
+ * @param[in] pdu1 CAN message 1
+ * @param[in] pdu2 CAN message 2
+ * @return TRUE, if the two CAN messages are equal.
+ */
+boolean_t cmd_can_messages_equal(const struct rpp_can_pdu *pdu1, const struct rpp_can_pdu *pdu2)
+{
+ boolean_t pdus_equal = TRUE;
+
+ if (pdu1->id != pdu2->id ||
+ pdu1->dlc != pdu2->dlc)
+ pdus_equal = FALSE;
+ else {
+ uint8_t i = 0;
+ for (i = 0; i < pdu1->dlc; i++) {
+ if (pdu1->data[i] != pdu1->data[i]) {
+ pdus_equal = FALSE;
+ break;
+ }
+ }
+ }
+ return pdus_equal;
+}
+
+/**
+ * Initialize the CAN bus driver for tests.
+ *
+ * @param[in] timing_calc Select RPP_CAN_TIMING_CALC_AUTO for automatic CAN bit timing calculation
+ * for a baudrate specified by desired_baudrate. Select RPP_CAN_TIMING_CALC_MANUAL for configuring the
+ * CAN bus to 500kbits/sec with verified bit timing parameters generated by HALCoGen.
+ *
+ * @return SUCCESS if the test passed, FAILURE otherwise.
+ */
+int cmd_can_test_init(enum rpp_can_timing_calculation timing_calc, uint32_t desired_baudrate)
+{
+ can_test_cfg.ctrl[0].baudrate = desired_baudrate;
+ can_test_cfg.ctrl[0].timing_calc_method = timing_calc;
+ can_test_cfg.ctrl[1].baudrate = desired_baudrate;
+ can_test_cfg.ctrl[1].timing_calc_method = timing_calc;
+ can_test_cfg.ctrl[2].baudrate = desired_baudrate;
+ can_test_cfg.ctrl[2].timing_calc_method = timing_calc;
+
+ if (rpp_can_init(&can_test_cfg) == SUCCESS)
+ return SUCCESS;
+ else
+ return FAILURE;
+}
+
+/**
+ * General test for receiving of message.
+ *
+ * This function verifies that the rpp_can_read() function is working
+ * properly and that the CAN driver behaves as expected.
+ *
+ * This is a blocking function that tries to receive a CAN message. The reception
+ * has to finish until specified timeout is reached.
+ * The received message is compared with the transmitted one.
+ *
+ * @param[in] can_tx_pdu A message pattern, which should be received. Used for RX
+ * and TX equality verification.
+ * @param[in] timeout How long should the test wait for the message.
+ * @return SUCCESS if the test passed, error code otherwise.
+ */
+int cmd_can_test_recv(const struct rpp_can_pdu *can_tx_pdu, uint32_t timeout)
+{
+ boolean_t msg_received = FALSE;
+ volatile uint32_t rec_time = 0;
+ struct rpp_can_pdu can_rx_pdu;
+
+ while (!msg_received) {
+ int ret = rpp_can_read(0, &can_rx_pdu);
+ switch (ret) {
+ case -RPP_EINVAL:
+ return ERR_CCT_HW_OBJ;
+ case -RPP_ENODATA:
+ if (++rec_time >= CCT_TIMEOUT)
+ return ERR_CCT_RECV_TIMEOUT;
+ break;
+ case SUCCESS:
+ if (!cmd_can_messages_equal(&can_rx_pdu, can_tx_pdu))
+ return ERR_CCT_MSG_MISMATCH;
+ else
+ msg_received = TRUE;
+ break;
+ default:
+ return ERR_CCT_UNEXPECTED_RETVAL;
+ }
+ }
+ return SUCCESS;
+}
+
+/**
+ * General test of sending a message.
+ *
+ * This function verifies that the rpp_can_write() function is working
+ * properly and that the CAN driver behaves as expected.
+ *
+ * @param[in] can_tx_msg A message for transmission.
+ * @return SUCCESS if the test passed, error code otherwise.
+ */
+int cmd_can_test_send(const struct rpp_can_pdu *can_tx_msg)
+{
+ if (rpp_can_write(0, can_tx_msg) != SUCCESS)
+ return ERR_CCT_HW_OBJ;
+ return SUCCESS;
+}
+
+/**
+ * General test of sending and receiving mechanism.
+ *
+ * This function verifies that the rpp_can_write() and rpp_can_read() functions
+ * are working properly and that the CAN driver behaves as expected.
+ *
+ * The message specified as a parameter is sent on the CAN bus and received to
+ * another mailbox. The received message is compared with the sent one.
+ *
+ * @param[in] can_tx_msg A message used to testing
+ * @return SUCCESS if the test passed, error code otherwise.
+ */
+int cmd_can_test_simple_send_recv(const struct rpp_can_pdu *can_tx_msg)
+{
+ int ret_val = 0;
+
+ if ((ret_val = cmd_can_test_send(can_tx_msg)) != SUCCESS)
+ return ERR_CCT_SEND|ret_val;
+ else if ((ret_val = cmd_can_test_recv(can_tx_msg, CCT_TIMEOUT)) != SUCCESS)
+ return ERR_CCT_RCV|ret_val;
+
+ return SUCCESS;
+}
+
+/**
+ * Test automatic CAN bit timing calculation for the specified baudrate.
+ *
+ * @param[in] tested_baudrate Desired baudrate.
+ * @param[in] can_tx_msg A message used to testing.
+ * @return SUCCESS if the test passed, error code otherwise.
+ *
+ */
+int cmd_can_test_baudrate_calc(uint32_t tested_baudrate,const struct rpp_can_pdu *can_tx_msg)
+{
+ int ret_val = 0;
+
+ if ((ret_val = cmd_can_test_init(RPP_CAN_TIMING_CALC_AUTO, 125000)) != SUCCESS)
+ return ERR_CCT_INIT|ret_val;
+ else if ((ret_val = cmd_can_test_simple_send_recv(can_tx_msg)) != SUCCESS)
+ return ret_val;
+
+ return SUCCESS;
+}
+
+/**
+ * Test behavioral of two consecutive TX requests posting.
+ *
+ * This function verifies that the rpp_can_write() function is working properly and
+ * that the CAN driver behaves as expected.
+ *
+ * According to the behavioral defined by tha Autosar, the rpp_can_write() should not fail when
+ * new transmission request comes before the previous one has been processed. The function should
+ * overwrite the old request and only the new one should be transmitted.
+ *
+ * @param[in] can_tx_msg1 A message which transmission is requested foremost.
+ * @param[in] can_tx_msg2 A message, which transmission is requested right after the can_tx_msg1
+ * @return SUCCESS if the test passed, error code otherwise.
+ */
+int cmd_can_test_tx_request_replace(const struct rpp_can_pdu *can_tx_msg1, const struct rpp_can_pdu *can_tx_msg2)
+{
+ int ret_val = 0;
+
+ if ((ret_val = cmd_can_test_send(can_tx_msg1)) != SUCCESS)
+ return ret_val;
+ else if ((ret_val = cmd_can_test_simple_send_recv(can_tx_msg2)) != SUCCESS)
+ return ret_val;
+
+ return SUCCESS;
+}
+
+/**
+ * Test the TX request flag.
+ *
+ * This function verifies that the rpp_can_check_tx_pend() function is working properly and
+ * that the CAN driver behaves as expected.
+ *
+ * The TX request flag should be clear if no transmission request is pending. Once a rpp_can_write()
+ * is called a new transmission requst is posted and the TX request flag should be set, until the CAN
+ * bus driver sends the message. After the transmission is finished, the flag should be cleared.
+ *
+ * @param[in] rpp_can_pdu A message which used to testing.
+ * @param[out] time Measured time between posting the transmission request and setting the TX request flag.
+ * @return SUCCESS if the test passed, error code otherwise.
+ */
+int cmd_can_test_tx_request_flag(const struct rpp_can_pdu *can_tx_msg, uint32_t *time)
+{
+ *time = 0;
+ uint32_t timeout = 0;
+ boolean_t tx_pend = FALSE;
+ int ret_val = 0;
+ if ((ret_val = cmd_can_test_send(can_tx_msg)) != SUCCESS)
+ return ret_val;
+ else {
+ /* Wait for the flag to be set */
+ while (!tx_pend) {
+ if (++timeout > CCT_TIMEOUT)
+ return ERR_CCT_SET_TX_PEND_TO;
+ if (rpp_can_check_tx_pend(0, &tx_pend) == FAILURE)
+ return ERR_CCT_HW_OBJ;
+ }
+ timeout = 0;
+ while (tx_pend) {
+ if (rpp_can_check_tx_pend(0, &tx_pend) == FAILURE)
+ return ERR_CCT_HW_OBJ;
+ (*time)++;
+ if (++timeout > CCT_TIMEOUT)
+ return ERR_CCT_CLEAR_TX_PEND_TO;
+ }
+ if ((ret_val = cmd_can_test_recv(can_tx_msg, CCT_TIMEOUT)) != SUCCESS)
+ return ERR_CCT_RCV|ret_val;
+ }
+
+ return SUCCESS;
+}
+
+/**
+ * Test the RX indicator.
+ *
+ * This function verifies that the rpp_can_check_rx_ind() function is working properly and
+ * that the CAN driver behaves as expected.
+ *
+ * The RX indicator should be set whenever new CAN message is received and remains set, until
+ * rpp_can_read() is called in order to retrieve the message.
+ *
+ * @param[in] rpp_can_pdu A message which used to testing.
+ * @param[out] time Measured time between posting the transmission request and setting the RX flag.
+ * @return SUCCESS if the test passed, error code otherwise.
+ */
+int cmd_can_test_rx_indicator(const struct rpp_can_pdu *can_tx_msg, uint32_t *time)
{
- dmmREG->PC4 = (1<<(13)); // set CAN_NSTB
- dmmREG->PC5 = (1<<(15)); // clr CAN_EN
- dmmREG->PC5 = (1<<(13)); // clr CAN_NSTB
- dmmREG->PC4 = (1<<(13)); // set CAN_NSTB
- dmmREG->PC4 = (1<<(15)); // set CAN_EN
+ *time = 0;
+ volatile uint32_t timeout = 0;
+ boolean_t rx_ind = FALSE;
+ int ret_val = 0;
+ struct rpp_can_pdu can_rx_pdu;
+
+ if ((ret_val = cmd_can_test_send(can_tx_msg)) != SUCCESS)
+ return ret_val;
+ else {
+ /* Wait for the flag to be set */
+ while (!rx_ind) {
+ if (rpp_can_check_rx_ind(0, &rx_ind) == FAILURE)
+ return ERR_CCT_HW_OBJ;
+ (*time)++;
+ if (++timeout > CCT_TIMEOUT)
+ return ERR_CCT_SET_TX_PEND_TO;
+ }
+
+ if ((ret_val = rpp_can_read(0, &can_rx_pdu)) != SUCCESS) {
+ switch (ret_val) {
+ case -RPP_ENODATA:
+ return ERR_CCT_RX_IND_SET_NO_MSG_REC;
+ case -RPP_EINVAL:
+ return ERR_CCT_HW_OBJ;
+ default:
+ return ERR_CCT_UNEXPECTED_RETVAL;
+ }
+ }
+ else {
+ if (!cmd_can_messages_equal(&can_rx_pdu, can_tx_msg))
+ return ERR_CCT_MSG_MISMATCH;
+ else {
+ if (rpp_can_check_rx_ind(0, &rx_ind) == FAILURE)
+ return ERR_CCT_HW_OBJ;
+ if (rx_ind == TRUE)
+ return ERR_CCT_RX_IND_NOT_CLEARED;
+ }
+ }
+ }
+ return SUCCESS;
+}
+/**
+ * Test CAN functions from RPP library.
+ *
+ * This is a complex test command for verification of automatic CAN bit timing
+ * calculation for baudrates 125k, 250k and 500kbits/sec and for checking RPP
+ * CAN functions:
+ * - rpp_can_init()
+ * - rpp_can_write()
+ * - rpp_can_read()
+ * - rpp_can_check_rx_ind()
+ * - rpp_can_check_tx_pend()
+ *
+ * @return always SUCCESS
+ */
+int cmd_do_can_test_functions(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
+{
+ struct rpp_can_pdu can_tx_msg1 = {
+ .id = 0x1,
+ .dlc = 8,
+ .data = {'H', 'E', 'L', 'L', 'O', '0', '0', '1'}
+ };
+
+ struct rpp_can_pdu can_tx_msg2 = {
+ .id = 0x1,
+ .dlc = 8,
+ .data = {'H', 'E', 'L', 'L', 'O', '0', '0', '2'}
+ };
+
+ rpp_sci_printf("This is a test for RPP CAN library functions:\n");
+ /*
+ * Simple send and receive a message with CAN bit time parameters for 500 kb/sec, picked
+ * from HALCoGen, which are proven to be functional.
+ */
+ rpp_sci_printf("Test of simple message transmission and reception.\n");
+ int ret_val = 0;
+ rpp_sci_printf("\tCAN bus Initialization: ");
+ if ((ret_val = cmd_can_test_init(RPP_CAN_TIMING_CALC_MANUAL, 500000)) != SUCCESS)
+ rpp_sci_printf("failed: error: 0x%X.\n", ret_val);
+ else {
+ rpp_sci_printf("OK\n");
+ rpp_sci_printf("\tTransmission and reception...");
+ if ((ret_val = cmd_can_test_simple_send_recv(&can_tx_msg1)) != SUCCESS)
+ rpp_sci_printf("failed: error: 0x%X.\n", ret_val);
+ else
+ rpp_sci_printf("OK\n");
+ }
+ rpp_sci_printf("---\n");
+ /* Baudrate calculation testing
+ *
+ * Based on EATON requirements for baudrates: 125k, 250k, 500k
+ * - calculate bit timing parameters,
+ * - initialize the CAN bus,
+ * - send a message
+ * - receive a message
+ * - test if the received message is OK.
+ */
+ uint32_t baudrates[] = {125000, 250000, 500000};
+ uint8_t num_baudrates = 3;
+ uint8_t i;
+ rpp_sci_printf("Test of automatic CAN bit timing calculation.\n");
+
+ for (i = 0; i < num_baudrates; i++) {
+ rpp_sci_printf("\tBaudrate: %d: ", baudrates[i]);
+ if ((ret_val = cmd_can_test_baudrate_calc(baudrates[i], &can_tx_msg1)) != SUCCESS)
+ rpp_sci_printf("failed: error: 0x%X.\n", ret_val);
+ else
+ rpp_sci_printf("OK\n");
+ }
+ rpp_sci_printf("---\n");
+
+ /*
+ * Test the behavioral when a new message replaces the actually pending message.
+ *
+ * - Send a request for message A transmission,
+ * - right after that, send a request for another message B transmission,
+ * - receive a message, which should be the message B.
+ */
+ rpp_sci_printf("Test of transmission request rewritting.\n");
+ rpp_sci_printf("\tCAN bus Initialization: ");
+ if ((ret_val = cmd_can_test_init(RPP_CAN_TIMING_CALC_MANUAL, 500000)) != SUCCESS)
+ rpp_sci_printf("failed: error: 0x%X.\n", ret_val);
+ else {
+ rpp_sci_printf("OK\n");
+ rpp_sci_printf("\tTX request rewritting...");
+ if ((ret_val = cmd_can_test_tx_request_replace(&can_tx_msg1, &can_tx_msg2)) != SUCCESS)
+ rpp_sci_printf("failed: error: 0x%X.\n", ret_val);
+ else
+ rpp_sci_printf("OK\n");
+ }
+ rpp_sci_printf("---\n");
+
+ /*
+ * Test the tx_pending flag detection
+ * - Send a request for a message transmission request,
+ * - Wait while the flag is reset, which means that the message has been received
+ * by another node, while measuring the time between the sending the request and
+ * resetting the flag.
+ * - Read the message to check that it has been already received.
+ *
+ */
+ rpp_sci_printf("Test of TX request pending flag detection.\n");
+ rpp_sci_printf("\tCAN bus Initialization: ");
+ if ((ret_val = cmd_can_test_init(RPP_CAN_TIMING_CALC_MANUAL, 500000)) != SUCCESS)
+ rpp_sci_printf("failed: error: 0x%X.\n", ret_val);
+ else {
+ rpp_sci_printf("OK\n");
+ uint32_t time = 0;
+ rpp_sci_printf("\tTX request pending flag behavioral: ");
+ if ((ret_val = cmd_can_test_tx_request_flag(&can_tx_msg1, &time)) != SUCCESS)
+ rpp_sci_printf("failed: error: 0x%X.\n", ret_val);
+ else
+ rpp_sci_printf("OK, time: %d cycles.\n", time);
+ }
+ rpp_sci_printf("---\n");
+
+ /*
+ * Test the rx_ind flag
+ * - Send a message
+ * - Wait for setting the rx_ind flag
+ * - Try to read the message.
+ */
+ rpp_sci_printf("Test of RX indicator.\n");
+ rpp_sci_printf("\tCAN bus Initialization: ");
+ if ((ret_val = cmd_can_test_init(RPP_CAN_TIMING_CALC_MANUAL, 500000)) != SUCCESS)
+ rpp_sci_printf("failed: error: 0x%X.\n", ret_val);
+ else {
+ rpp_sci_printf("OK\n");
+ uint32_t time = 0;
+ rpp_sci_printf("\tRX indicator behavioral: ");
+ if ((ret_val = cmd_can_test_rx_indicator(&can_tx_msg1, &time)) != SUCCESS)
+ rpp_sci_printf("failed: error: 0x%X.\n", ret_val);
+ else
+ rpp_sci_printf("OK, time: %d cycles.\n", time);
+ }
+ rpp_sci_printf("---\n");
+
+ /*
+ * Reset the CAN bus to a determined state
+ * Baudrate: 500kb
+ */
+ rpp_sci_printf("Reset the CAN bus.\n");
+ rpp_sci_printf("\tCAN bus Initialization: ");
+ if ((ret_val = cmd_can_test_init(RPP_CAN_TIMING_CALC_MANUAL, 500000)) != SUCCESS)
+ rpp_sci_printf("failed: error: 0x%X.\n", ret_val);
+ else
+ rpp_sci_printf("OK\n");
+ return SUCCESS;
+}
- can_inited = (rpp_can_init(&can_config) == SUCCESS ? 1 : 0);
- return (can_inited ? 0 : 1);
+int cmd_do_can_init(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
+{
+ can_inited = (rpp_can_init(&can_config) == SUCCESS ? 1 : 0);
+ return (can_inited ? 0 : 1);
}
struct rpp_can_pdu pdu;
char *p;
- if (!can_inited)
- {
- rpp_sci_printf("WARNING: CAN is not initialized\n");
+ if (!can_inited) {
+ rpp_sci_printf("CAN is not initialized\n");
+ return -CMDERR_NODEV;
}
p = param[1];
ret = sscanf(p, "%i %i%n", &controller_id, &pdu.id, &l);
- if (ret < 2)
- {
+ if (ret < 2) {
rpp_sci_printf("Cannot parse parameter %d\n", ret+1);
return -CMDERR_BADPAR;
}
i = 0;
do {
- ret = sscanf(p, "%2hhx%n", &pdu.data[i], &l);
+ uint16_t data;
+ ret = sscanf(p, "%2hx%n", &data, &l);
if (ret < 1) break;
+ pdu.data[i] = data & 0xff;
i++;
p += l;
} while (1);
pdu.dlc = i;
- if (rpp_can_write(controller_id-1, &pdu) == SUCCESS)
- {
+ if (rpp_can_write(controller_id-1, &pdu) == SUCCESS) {
rpp_sci_printf("Sent: can%u\t%X\t[%u]\t", controller_id, pdu.id, pdu.dlc);
- for (i=0; i<pdu.dlc; i++)
- {
+ for (i = 0; i < pdu.dlc; i++) {
rpp_sci_printf("%X ", pdu.data[i]);
}
}
else
- {
rpp_sci_printf("Error: rpp_can_write");
- }
rpp_sci_printf("\n");
uint32_t i;
- if (!can_inited)
- {
- rpp_sci_printf("WARNING: CAN is not initialized\n");
+ if (!can_inited) {
+ rpp_sci_printf("CAN is not initialized\n");
+ return -CMDERR_NODEV;
}
- if (!(sscanf(param[1], "%u", &controller_id) == 1))
- {
+ if (!(sscanf(param[1], "%u", &controller_id) == 1)) {
rpp_sci_printf("Unable to parse controller ID\n");
return 1;
}
+ if (controller_id < 1 || controller_id > 3) {
+ rpp_sci_printf("Invalid controller ID\n");
+ return -CMDERR_NODEV;
+ }
+
rpp_can_init(&can_config);
- while(cmd_io->getc(cmd_io) < 0)
- {
+ while (cmd_io->getc(cmd_io) < 0) {
rpp_can_check_rx_ind(controller_id-1, &rx_ind);
- if (rx_ind)
- {
- if (rpp_can_read(controller_id-1, &pdu) == SUCCESS)
- {
+ if (rx_ind) {
+ if (rpp_can_read(controller_id-1, &pdu) == SUCCESS) {
if (pdu.id & CAN_EFF_FLAG)
- {
rpp_sci_printf("can%u %08X [%u] ", controller_id & (~CAN_EFF_FLAG), pdu.id, pdu.dlc);
- }
else
- {
rpp_sci_printf("can%u %03X [%u] ", controller_id, pdu.id, pdu.dlc);
- }
- for (i=0; i<pdu.dlc; i++)
- {
- rpp_sci_printf("%X ", pdu.data[i]);
+ for (i = 0; i < pdu.dlc; i++) {
+ rpp_sci_printf("%X ", pdu.data[i]);
}
rpp_sci_printf("\n");
}
else
- {
rpp_sci_printf("Error rpp_can_read\n");
- }
}
}
if ((opchar = cmd_opchar_check(cmd_io, des, param)) < 0)
return opchar;
- if (opchar == ':')
- {
- if (!(sscanf(param[1], "%u:%u", &controller_id, &baudrate) == 2))
- {
+ if (opchar == ':') {
+ if (!(sscanf(param[1], "%u:%u", &controller_id, &baudrate) == 2)) {
rpp_sci_printf("Unable to parse arguments\n");
return 1;
}
return -CMDERR_BADPAR;
can_config.ctrl[controller_id-1].baudrate = baudrate;
+ can_config.ctrl[controller_id-1].timing_config = NULL;
+ can_config.ctrl[controller_id-1].timing_calc_method = RPP_CAN_TIMING_CALC_AUTO;
}
else
{
if (!(sscanf(param[1], "%u", &controller_id) == 1))
+ if (controller_id < 1 || controller_id > 3)
+ return -CMDERR_BADPAR;
+
+ cmd_opchar_replong(cmd_io, param, can_config.ctrl[controller_id-1].baudrate, 0, 10);
+ }
+
+ return 0;
+}
+
+int cmd_do_can_change_timing(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
+{
+ int opchar;
+ uint32_t controller_id, brp, prop_seg, phase_seg1, phase_seg2, sjw;
+
+ if ((opchar = cmd_opchar_check(cmd_io, des, param)) < 0)
+ return opchar;
+
+ if (opchar == ':') {
+ if (!(sscanf(param[1], "%u:%u %u %u %u %u", &controller_id, &brp, &prop_seg, &phase_seg1, &phase_seg2, &sjw) == 6)) {
+ rpp_sci_printf("Unable to parse arguments\n");
+ return 1;
+ }
+
if (controller_id < 1 || controller_id > 3)
return -CMDERR_BADPAR;
- cmd_opchar_replong(cmd_io, param, can_config.ctrl[controller_id-1].baudrate, 0, 10);
+ can_config.ctrl[controller_id-1].baudrate = 0;
+ can_config.ctrl[controller_id-1].timing_config = &can_timing[controller_id-1];
+ can_config.ctrl[controller_id-1].timing_config->brp = brp;
+ can_config.ctrl[controller_id-1].timing_config->phase_seg1 = phase_seg1;
+ can_config.ctrl[controller_id-1].timing_config->phase_seg2 = phase_seg2;
+ can_config.ctrl[controller_id-1].timing_config->prop_seg = prop_seg;
+ can_config.ctrl[controller_id-1].timing_config->sjw = sjw;
+ can_config.ctrl[controller_id-1].timing_calc_method = RPP_CAN_TIMING_CALC_MANUAL;
+ }
+ else
+ {
+ if (!(sscanf(param[1], "%u", &controller_id) == 1))
+
+ if (controller_id < 1 || controller_id > 3)
+ return -CMDERR_BADPAR;
+
+ if (can_config.ctrl[controller_id-1].timing_config != NULL)
+ rpp_sci_printf("brp: %u\r\nprop_seg: %u tQ\r\nphase_seg1: %u tQ\r\nphase_seg2: %u tQ\r\nsjw: %u tQ\r\n",
+ can_config.ctrl[controller_id-1].timing_config->brp,
+ can_config.ctrl[controller_id-1].timing_config->prop_seg,
+ can_config.ctrl[controller_id-1].timing_config->phase_seg1,
+ can_config.ctrl[controller_id-1].timing_config->phase_seg2,
+ can_config.ctrl[controller_id-1].timing_config->sjw
+ );
+
+ else
+ rpp_sci_printf("CAN timing has not yet been manually specified.\r\n");
}
return 0;
-#endif /* DOCGEN */
-/** @brief command descriptor for test CAN loopback command */
-cmd_des_t const cmd_des_test_can_loopback={
- 0, 0,
- "cantest*", "Test CAN loopback between two CAN interfaces",
- "=== Command syntax ===\n"
- "\n"
- " cantest<SOURCE> <DESTINATION>\n"
- "\n"
- "where <SOURCE> and <DESTINATION> are different numbers in range 1-3.\n"
- "\n"
- "=== Description ===\n"
- "\n"
- "This command tests CAN communication by sending and receiving messages\n"
- "through external loopback. At the beginning, the involved CAN\n"
- "controller are initialized to the Bus-On state.\n"
- "\n"
- "The command sends 100 messages and measures the numbers of TX errors,\n"
- "RX errors and detected timeouts. At the end, these statistics are\n"
- "printed as well as the status of the involved CAN controllers.\n"
- "\n"
- "When an error is detected during the test, the status of faulty CAN\n"
- "controller is printed immediately.\n"
- "\n"
- "=== Example ===\n"
- "\n"
- " --> cantest1 2\n"
- " Testing CAN loopback\n"
- " Messages transmitted: 100/100\n"
- " Messages received: 100/100\n"
- " TX timeouts: 0\n"
- " RX timeouts: 0\n"
- " Src TX error counter: 0\n"
- " Src RX error counter: 0\n"
- " Dst TX error counter: 0\n"
- " Dst RX error counter: 0\n"
- " CAN1 status: Bus-On, ES: 0x8\n"
- " CAN2 status: Bus-On, ES: 0x10\n",
- CMD_HANDLER(cmd_do_test_can_loopback), (void *)&cmd_list_can
+#endif /* DOCGEN */
+
+cmd_des_t const cmd_des_can_init = {
+ 0, 0,
+ "caninit", "Initialize CAN controllers",
+ "### Command syntax ###\n"
+ "\n"
+ " caninit\n"
+ "\n"
+ "### Description ###\n"
+ "\n"
+ "This command (re-)initializes all CAN controllers using current\n"
+ "CAN configuration. This configuration can be changed using\n"
+ "canbaudrate command.\n"
+ "\n"
+ "In the default configuration the baudrate of all CAN controllers i set\n"
+ "to 500 kbit/s.\n"
+ "\n"
+ "### Example ###\n"
+ " --> caninit\n",
+ CMD_HANDLER(cmd_do_can_init), (void *)&cmd_list_can
};
+cmd_des_t const cmd_des_can_baudrate = {
+ 0, CDESM_OPCHR|CDESM_RW,
+ "canbaudrate#", "Change baudrate of CAN controller",
+ "### Command syntax ###\n"
+ "\n"
+ " canbaudrate<CONTROLLER>?\n"
+ " canbaudrate<CONTROLLER>:<BAUDRATE>\n"
+ "\n"
+ "where `<CONTROLLER>` is number in range 1-3 and BAUDRATE is number in\n"
+ "range 1000-10000000 specifying the baudrate in bits per second.\n"
+ "\n"
+ "### Description ###\n"
+ "\n"
+ "This command is used to set or show the baudrate of a CAN controller.\n"
+ "The baudrate shown is the one which will be used by next invocation of\n"
+ "the caninit command.\n"
+ "The baudrate specified by the command is used to automatic calculation of\n"
+ "the CAN controller timing. If you want to specify the timing manually,\n"
+ "please use the command cantiming.\n"
+ "The automatic calculation might not work properly for some baudrates. In\n"
+ "this case you should calculate the timing manually and specify it by the\n"
+ "command cantiming."
+ "\n"
+ "### Examples ###\n"
+ "\n"
+ " --> canbaudrate2?\n"
+ " canbaudrate2=500000\n"
+ "\n"
+ " --> canbaudrate2:100000\n",
+ CMD_HANDLER(cmd_do_can_change_baudrate), (void *)&cmd_list_can
+};
-cmd_des_t const cmd_des_can_init={
- 0, 0,
- "caninit", "Initialize CAN controllers",
- "=== Command syntax ===\n"
- "\n"
- " caninit\n"
- "\n"
- "=== Description ===\n"
- "\n"
- "This command (re-)initializes all CAN controllers using current\n"
- "CAN configuration. This configuration can be changed using\n"
- "canbaudrate command.\n"
- "\n"
- "Default configuration sets baudrate of all CAN controllers to 0.5 Mbit/s\n"
- "\n"
- "=== Example ===\n"
- " --> caninit\n",
- CMD_HANDLER(cmd_do_can_init), (void *)&cmd_list_can
+cmd_des_t const cmd_des_can_timing = {
+ 0, CDESM_OPCHR|CDESM_RW,
+ "cantiming#", "Change timing of CAN controller manually",
+ "### Command syntax ###\n"
+ "\n"
+ " cantiming<CONTROLLER>?\n"
+ " cantiming<CONTROLLER>:<BRP> <PROP_SEG> <PHASE_SEG1> <PHASE_SEG2> <SJW>\n"
+ "\n"
+ "where:"
+ " - `<CONTROLLER>` is number in range 1-3\n"
+ " - `<BRP>` (baudrate prescaler) is number in range 1-65\n"
+ " - `<PROP_SEG>` (length of propagation segment in tQ) is a number in range 1-8\n"
+ " - `<PHASE_SEG1>` (phase buffer segment 1 in tQ) is a number in range 1-8\n"
+ " - `<PHASE_SEG2>` (phase buffer segment 2 in tQ) is a number in range 1-8\n"
+ " - `<SJW>` (synchronization jump width in tQ) is a number in range 1-4\n"
+ "\n"
+ "### Description ###\n"
+ "\n"
+ "This command is used to set or show the timing of a CAN controller.\n"
+ "The timing shown is the one which will be used by next invocation of\n"
+ "the caninit command.\n"
+ "The timing configured by this command defines manually the baudrate of\n"
+ "the CAN controller. If you want to calculate the timing automaticaly from\n"
+ "a baudrate, please use the command canbaudrate.\n"
+ "\n"
+ "### Examples ###\n"
+ "\n"
+ " --> cantiming2?\n"
+ " brp: 17\n"
+ " prop_seg: 4 tQ\n"
+ " phase_seg1: 5 tQ\n"
+ " phase_seg2: 5 tQ\n"
+ " sjw: 4 tQ\n"
+ " sample_pt: 875 ns\n"
+ " error: 0\n"
+ " tQ: 125 ns\n"
+ "\n"
+ " --> cantiming2:5 8 7 4 1\n",
+ CMD_HANDLER(cmd_do_can_change_timing), (void *)&cmd_list_can
+};
+
+
+cmd_des_t const cmd_des_can_send = {
+ 0, 0,
+ "cansend", "Test sending message over CAN",
+ "### Command syntax ###\n"
+ "\n"
+ " cansend <CONTROLLER> <ID> <DATA>\n"
+ "\n"
+ "where `<CONTROLLER>` is number in range 1-3, `<ID>` is a valid CAN ID\n"
+ "and `<DATA>` is 0-8 bytes of data in hexadecimal representation.\n"
+ "There may be any number of spaces between the data bytes.\n"
+ "`<ID>` may be given in octal, decimal or hexadecimal base.\n"
+ "\n"
+ "### Description ###\n"
+ "\n"
+ "This command sends a CAN frame using specified CAN controller.\n"
+ "\n"
+ "The caninit command must be called before using this command.\n"
+ "\n"
+ "### Example ###\n"
+ " --> cansend 2 0x123 DEAD BEEF\n"
+ " Sent: can2 123 [4] DE AD BE EF\n",
+ CMD_HANDLER(cmd_do_can_send), (void *)&cmd_list_can
};
-cmd_des_t const cmd_des_can_baudrate={
- 0, CDESM_OPCHR|CDESM_RW,
- "canbaudrate#", "Change baudrate of CAN controller",
- "=== Command syntax ===\n"
+
+cmd_des_t const cmd_des_can_dump = {
+ 0, 0,
+ "candump", "Dump all messages received over CAN",
+ "### Command syntax ###\n"
+ "\n"
+ " candump <CONTROLLER>\n"
+ "\n"
+ "where `<CONTROLLER>` is a number in range 1-3.\n"
+ "\n"
+ "### Description ###\n"
+ "\n"
+ "This command prints out all CAN messages received via the specified\n"
+ "controller.\n"
+ "\n"
+ "IDs are zero-filled to length 3 if a message in the standard frame\n"
+ "format is received and to 8 for extended frame format messages.\n"
+ "\n"
+ "`caninit` must be called before using this command.\n"
+ "\n"
+ "### Example ###\n"
+ "\n"
+ " --> candump 2\n"
+ " can2 0000FADE [2] 12 34\n",
+ CMD_HANDLER(cmd_do_can_dump), (void *)&cmd_list_can
+};
+
+cmd_des_t const cmd_des_can_test={
+ 0, 0,
+ "canrpptest", "Test the CAN functions from the RPP library",
+ "### Command syntax ###\n"
"\n"
- " canbaudrate<CONTROLLER>?\n"
- " canbaudrate<CONTROLLER>:<BAUDRATE>\n"
+ " canrpptest\n"
"\n"
- "where <CONTROLLER> is number in range 1-3 and BAUDRATE is number\n"
- "in range 1000-10000000.\n"
+ "### Description ###\n"
"\n"
- "=== Description ===\n"
+ "This command tests all CAN functions in the RPP library. It requires\n"
+ "the CAN1 and CAN2 connectors to be connected with HW loopback. The\n"
+ "following tests are performed:\n"
"\n"
- "This command is used to set or show baudrate of CAN controller.\n"
- "The baudrate shown is the one which would be set if caninit was\n"
- "called now.\n"
+ "1. Test of `rpp_can_init()`, `rpp_can_write()` and `rpp_can_read()` functions.\n"
"\n"
- "=== Examples ===\n"
+ " At the beginning, the CAN bus is initialized with hardcoded (and\n"
+ " verified) verified CAN bit timing parameters. Then a message is\n"
+ " sent to the CAN1 interface and received from CAN2. The received\n"
+ " message is compared with the sent one. If the transmissions fails,\n"
+ " reception exceeds a timeout or the sent and received messages\n"
+ " differ, the command prints an appropriate error code.\n"
"\n"
- " --> canbaudrate2?\n"
- " canbaudrate2=500000\n"
+ "2. Test of CAN bit timing parameters calculation.\n"
"\n"
- " --> canbaudrate2:100000\n",
- CMD_HANDLER(cmd_do_can_change_baudrate), (void *)&cmd_list_can
-};
-
-cmd_des_t const cmd_des_can_send={
- 0, 0,
- "cansend", "Test sending message over CAN",
- "=== Command syntax ===\n"
+ " This test subsequently initializes the CAN controller to baudrates\n"
+ " 125k, 250k and 500k. For each one of them a message is sent to\n"
+ " CAN1 and received from CAN2. The received message is compared with\n"
+ " the sent one like in test 1. If the initialization, transmission,\n"
+ " reception or comparison fails or if the reception timeout is\n"
+ " reached, an appropriate error code is printed.\n"
"\n"
- " cansend <CONTROLLER> <ID> <DATA>\n"
+ "3. Test of the behavior of transmission request overwriting.\n"
"\n"
- "where <CONTROLLER> is number in range 1-3, <ID> is valid CAN ID\n"
- "and <DATA> is 0-8 bytes of data in hexadecimal representation.\n"
- "There may be any number of spaces between data bytes.\n"
- "<ID> may be given in octal, decimal or hexadecimal base.\n"
+ " The CAN controller is initialized as in test 1. A transmission\n"
+ " request for message A is made on CAN1 by calling `rpp_can_write()`.\n"
+ " Right after that another transmission request for message B is\n"
+ " made on CAN1 by another call to `rpp_can_write()`. A message B is\n"
+ " received on CAN2, because the second request came so quickly, that\n"
+ " it overwrote message A in the TX buffer. The sent and received\n"
+ " messages are compared to verify that the behavior was correct.\n"
"\n"
- "=== Description ===\n"
+ " If the initialization, transmission, reception or comparison fails\n"
+ " or if the reception timeout is reached, an appropriate error code\n"
+ " is printed.\n"
"\n"
- "This command sends a CAN frame using specified CAN controller.\n"
+ "4. Test of the TX request pending flag detection.\n"
"\n"
- "caninit shall be called before using this command, sending may\n"
- "behave unexpectedly otherwise.\n"
+ " The CAN bus is initialized like in test 1. A message is\n"
+ " transmitted on CAN1 and the test waits for the TX pending flag to\n"
+ " be set, which signalizes that there is a message transmission\n"
+ " request pending. After the flag has been set, the test waits for\n"
+ " its clearance, which means that the message has been sent. The\n"
+ " test measures, how many flag test cycles passed, until the flag\n"
+ " has been cleared. This value is then presented as time. At the\n"
+ " end, the message is received from CAN2 and it is compared with the\n"
+ " sent message for verification.\n"
"\n"
- "=== Example ===\n"
- " --> cansend 2 0x123 DEAD BEEF\n"
- " Sent: can2 123 [4] DE AD BE EF\n",
- CMD_HANDLER(cmd_do_can_send), (void *)&cmd_list_can
-};
-
-
-cmd_des_t const cmd_des_can_dump={
- 0, 0,
- "candump", "Dump all messages received over CAN",
- "=== Command syntax ===\n"
+ " If the initialization, transmission, reception or comparison fails or if\n"
+ " timeout is reached while waiting for the flag set/clear or receive timeout\n"
+ " is reached, an appropriate error code is printed.\n"
"\n"
- " candump <CONTROLLER>\n"
+ "5. Test of the message received (RX) indication.\n"
"\n"
- "where <CONTROLLER> is number in range 1-3.\n"
+ " The CAN bus is initialized like in test 1. A message is\n"
+ " transmitted on CAN1. The test then waits for the RX indication to\n"
+ " be set, which indicates that a message has been received. The\n"
+ " message is picked up by calling `rpp_can_read()`. This should\n"
+ " clear the indicator, which is tested. Finally the received\n"
+ " messages is compared with the sent one.\n"
"\n"
- "=== Description ===\n"
+ " If the initialization, transmission, reception, message comparison or indicator\n"
+ " test fails or if timeout is reached while waiting for the flag set, the\n"
+ " appropriate error code is printed.\n"
"\n"
- "This command prints out any CAN message received via specified\n"
- "controller.\n"
+ "At the end the CAN bus is reset and left with the configuration from\n"
+ "test 1.\n"
"\n"
- "IDs are zero-filled to length 3 if standard ID is used and to 8\n"
- "if extended ID is used.\n"
+ "The command can be called even after the CAN bus has been already\n"
+ "configured by previous invocation of the `caninit` command. The\n"
+ "previous timing configuration set by `cantiming#` command not\n"
+ "modified. Therefore, calling `caninit` after this command finishes\n"
+ "restores the previous timing settings.\n"
"\n"
- "caninit shall be called before using this command, dump may\n"
- "behave unexpectedly otherwise.\n"
+ "For error codes description please refer to the API documentation for\n"
+ "the rpp-test-sw.\n"
"\n"
- "=== Example ===\n"
+ "### Example ###\n"
"\n"
- " --> candump 2\n"
- "can2 0000FADE [2] 12 34\n",
- CMD_HANDLER(cmd_do_can_dump), (void *)&cmd_list_can
+ " --> canrpptest\n"
+ " This is a test for RPP CAN library functions:\n"
+ " Test of simple message transmission and reception.\n"
+ " CAN bus Initialization...OK\n"
+ " Transmission and reception...OK\n"
+ " ---\n"
+ " Test of automatic CAN bit timing calculation.\n"
+ " Baudrate: 125000: OK\n"
+ " Baudrate: 250000: OK\n"
+ " Baudrate: 500000: OK\n"
+ " ---\n"
+ " Test of transmission request rewritting.\n"
+ " CAN bus Initialization...OK\n"
+ " TX request rewritting...OK\n"
+ " ---\n"
+ " Test of TX request pending flag detection.\n"
+ " CAN bus Initialization...OK\n"
+ " TX request pending flag behavioral: OK, time: 256 cycles.\n"
+ " ---\n"
+ " Test of RX indicator.\n"
+ " CAN bus Initialization...OK\n"
+ " RX indicator behavioral:\n"
+ " OK, time: 0 cycles.\n"
+ " ---\n"
+ " Reset the CAN bus.\n"
+ " CAN bus Initialization...OK\n",
+ CMD_HANDLER(cmd_do_can_test_functions), (void *)&cmd_list_can
};
-cmd_des_t const *cmd_list_can[]={
- &cmd_des_test_can_loopback,
- &cmd_des_can_init,
- &cmd_des_can_baudrate,
- &cmd_des_can_send,
- &cmd_des_can_dump,
- NULL
+
+cmd_des_t const *cmd_list_can[] = {
+ &cmd_des_can_init,
+ &cmd_des_can_baudrate,
+ &cmd_des_can_timing,
+ &cmd_des_can_send,
+ &cmd_des_can_dump,
+ &cmd_des_can_test,
+ NULL
};