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
}
};
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
{
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 */
" 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"
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",
&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