]> rtime.felk.cvut.cz Git - pes-rpp/rpp-test-sw.git/commitdiff
CAN baudrate setting fixed, manual CAN timing parameters specification implemented
authorMichal Horn <hornmich@fel.cvut.cz>
Thu, 9 Oct 2014 10:50:52 +0000 (12:50 +0200)
committerMichal Horn <hornmich@fel.cvut.cz>
Thu, 9 Oct 2014 10:50:52 +0000 (12:50 +0200)
The previous command for baudrate setting was calling a function
implementing wrong algorithm for timing parameters calculation.
The modified command is using the updated function from the library.

There is a new command for manual specification of the CAN frame timing,
instead of automatic calculation from desired baudrate, which might not work
for some values.

rpp-lib
rpp-test-sw/commands/cmd_can.c

diff --git a/rpp-lib b/rpp-lib
index 78af970551012861151f1ef857a24ad8f4a8c61d..0eb8a8209d083134ff7eb15536e81a0b02835c9e 160000 (submodule)
--- a/rpp-lib
+++ b/rpp-lib
@@ -1 +1 @@
-Subproject commit 78af970551012861151f1ef857a24ad8f4a8c61d
+Subproject commit 0eb8a8209d083134ff7eb15536e81a0b02835c9e
index 2246cec02b629bb2321f46865db34263bf1fa909..2f0db9268c50d5a2317a58e92d357d5c71f89578 100644 (file)
@@ -210,15 +210,62 @@ int cmd_do_test_can_loopback(cmd_io_t *cmd_io, const struct cmd_des *des, char *
 
 static int can_inited = 0;
 
+/* Default CAN timing set to 500kb */
+static struct rpp_can_timing_cfg can_timing[] = {
+       {
+               .brp = 10,
+               .error = 0,
+               .phase_seg1 = 5,
+               .phase_seg2 = 2,
+               .prop_seg = 8,
+               .sampl_pt = 875,
+               .sjw = 1,
+               .tq = 125
+       },
+       {
+               .brp = 10,
+               .error = 0,
+               .phase_seg1 = 5,
+               .phase_seg2 = 2,
+               .prop_seg = 8,
+               .sampl_pt = 875,
+               .sjw = 1,
+               .tq = 125
+       },
+       {
+               .brp = 10,
+               .error = 0,
+               .phase_seg1 = 5,
+               .phase_seg2 = 2,
+               .prop_seg = 8,
+               .sampl_pt = 875,
+               .sjw = 1,
+               .tq = 125
+       },
+};
+
+
 static struct rpp_can_ctrl_config ctrl_config[] = {
        {
-               .baudrate = 500000
+               .baudrate = 500000,
+               .clk = 80000000,
+               .prop_delay = 700,
+               .timing_calc_method = RPP_CAN_TIMING_CALC_AUTO,
+               .timing_config = NULL
        },
        {
-               .baudrate = 500000
+               .baudrate = 500000,
+               .clk = 80000000,
+               .prop_delay = 700,
+               .timing_calc_method = RPP_CAN_TIMING_CALC_AUTO,
+               .timing_config = NULL
        },
        {
-               .baudrate = 500000
+               .baudrate = 500000,
+               .clk = 80000000,
+               .prop_delay = 700,
+               .timing_calc_method = RPP_CAN_TIMING_CALC_AUTO,
+               .timing_config = NULL
        }
 };
 
@@ -418,6 +465,8 @@ int cmd_do_can_change_baudrate(cmd_io_t *cmd_io, const struct cmd_des *des, char
                        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
        {
@@ -432,6 +481,63 @@ int cmd_do_can_change_baudrate(cmd_io_t *cmd_io, const struct cmd_des *des, char
        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;
+
+               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\nsample_pt: %u ns\r\nerror: %u\r\n tQ: %u ns\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,
+                                       can_config.ctrl[controller_id-1].timing_config->sampl_pt,
+                                       can_config.ctrl[controller_id-1].timing_config->error,
+                                       can_config.ctrl[controller_id-1].timing_config->tq
+                       );
+
+               }
+               else {
+                       rpp_sci_printf("CAN timing has not yet been manualy specified.\r\n");
+               }
+       }
+
+       return 0;
+}
+
+
 
 
 #endif /* DOCGEN */
@@ -507,13 +613,19 @@ cmd_des_t const cmd_des_can_baudrate={
     "    canbaudrate<CONTROLLER>:<BAUDRATE>\n"
     "\n"
     "where `<CONTROLLER>` is number in range 1-3 and BAUDRATE is number in\n"
-    "range 1000-10000000 specifying the baurdate in bits per second.\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"
@@ -524,6 +636,48 @@ cmd_des_t const cmd_des_can_baudrate={
     CMD_HANDLER(cmd_do_can_change_baudrate), (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",
@@ -581,6 +735,7 @@ cmd_des_t const *cmd_list_can[]={
   &cmd_des_test_can_loopback,
   &cmd_des_can_init,
   &cmd_des_can_baudrate,
+  &cmd_des_can_timing,
   &cmd_des_can_send,
   &cmd_des_can_dump,
   NULL