summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--src/canconfig.c122
2 files changed, 118 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog
index 09cfd30..071818a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2007-10-02 Juergen Beisert
+
+ * canconfig: adding support for manually calculated bit rate configurations
+
2005-03-16 Robert Schwebel
* framework: collected all tools and autotoolized
diff --git a/src/canconfig.c b/src/canconfig.c
index 685f8a4..9c33cf3 100644
--- a/src/canconfig.c
+++ b/src/canconfig.c
@@ -2,6 +2,7 @@
* canutils/canconfig.c
*
* Copyright (C) 2005 Marc Kleine-Budde <mkl@pengutronix.de>, Pengutronix
+ * Copyright (C) 2007 Juergen Beisert <jbe@pengutronix.de>, Pengutronix
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the version 2 of the GNU General Public License
@@ -40,7 +41,12 @@
#ifndef MIN
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#endif
-
+
+#define kHz 1000
+
+#define CONFIG_FILE_NAME "/etc/canconfig.conf"
+/* #define CONFIG_FILE_NAME "./canconfig.conf" */
+
int s;
struct ifreq ifr;
@@ -51,13 +57,20 @@ static void help(void)
"BR := <baudrate>\n\t\t"
"canconfig <dev> mode MODE\n\t\t"
"MODE := { start }\n\t"
- "canconfig <dev> state\n"
+ "canconfig <dev> tweak [ VALs ]\n\t\t"
+ "VALs := <TBR SYS PPS PHS1 PHS2 SJW>\n\t\t"
+ " TBR bit rate to be tweaked in kHz\n\t\t"
+ " SYS Sync_Seg in tq\n\t\t"
+ " PPS Prop_Seg in tq\n\t\t"
+ " PHS1 Phase_Seg1 in tq\n\t\t"
+ " PHS2 Phase_Seg2 in tq\n\t\t"
+ " SJW in tq\n\t\t"
+ " without VALSs " CONFIG_FILE_NAME " will be read\n"
);
exit(EXIT_FAILURE);
}
-
static void do_show_baudrate(int argc, char* argv[])
{
uint32_t *baudrate = (uint32_t *)&ifr.ifr_ifru;
@@ -72,7 +85,7 @@ static void do_show_baudrate(int argc, char* argv[])
if (*baudrate != -1)
fprintf(stdout,
- "%s: baudrate %d\n", ifr.ifr_name, *baudrate / 1000);
+ "%s: baudrate %d\n", ifr.ifr_name, *baudrate / kHz);
else
fprintf(stdout,
"%s: baudrate unknown\n", ifr.ifr_name);
@@ -85,7 +98,7 @@ static void do_set_baudrate(int argc, char* argv[])
uint32_t *baudrate = (uint32_t *)&ifr.ifr_ifru;
int i;
- *baudrate = (uint32_t)strtoul(argv[3], NULL, 0) * 1000;
+ *baudrate = (uint32_t)strtoul(argv[3], NULL, 0) * kHz;
if (*baudrate == 0) {
fprintf(stderr, "invalid baudrate\n");
exit(EXIT_FAILURE);
@@ -128,10 +141,100 @@ static void cmd_mode(int argc, char *argv[])
perror("ioctl");
exit(EXIT_FAILURE);
}
-
+
+ exit(EXIT_SUCCESS);
+}
+
+static void tweak_a_bitrate(uint32_t bit_rate, uint32_t sync_seg,
+ uint32_t prop_seg, uint32_t phase_seg1, uint32_t phase_seg2,
+ uint32_t sjw)
+{
+}
+
+static void tweak_from_command_line(int argc, char *argv[])
+{
+ uint32_t bit_rate;
+ uint32_t sync_seg;
+ uint32_t prop_seg;
+ uint32_t phase_seg1;
+ uint32_t phase_seg2;
+ uint32_t sjw;
+
+ if (argc < 9)
+ help();
+
+ bit_rate = (uint32_t)strtoul(argv[3], NULL, 0);
+ sync_seg = (uint32_t)strtoul(argv[4], NULL, 0);
+ prop_seg = (uint32_t)strtoul(argv[5], NULL, 0);
+ phase_seg1 = (uint32_t)strtoul(argv[6], NULL, 0);
+ phase_seg2 = (uint32_t)strtoul(argv[7], NULL, 0);
+ sjw = (uint32_t)strtoul(argv[8], NULL, 0);
+
+ tweak_a_bitrate(bit_rate, sync_seg, prop_seg, phase_seg1, phase_seg2,
+ sjw);
+}
+
+static void tweak_from_config_file(int argc, char *argv[])
+{
+ FILE *config_file;
+ int first_char,cnt,line = 1;
+ uint32_t bit_rate;
+ uint32_t sync_seg;
+ uint32_t prop_seg;
+ uint32_t phase_seg1;
+ uint32_t phase_seg2;
+ uint32_t sjw;
+
+ config_file = fopen(CONFIG_FILE_NAME, "r");
+ if (config_file == NULL) {
+ perror("Config file (" CONFIG_FILE_NAME ")");
+ exit(EXIT_FAILURE);
+ }
+
+ while(!feof(config_file)) {
+ first_char = fgetc(config_file);
+ printf("First char in line %d is: %02x (%c)\n", line, first_char, first_char);
+ if (first_char == EOF)
+ break;
+ if (first_char == '#') {
+ printf("eating line %d ", line);
+ cnt=fscanf(config_file,"%*[^\n]"); /* eat the whole line */
+ printf("-> %d\n", cnt);
+ fgetc(config_file); /* FIXME: eat the \n */
+ line ++;
+ continue;
+ }
+ else
+ ungetc(first_char, config_file);
+
+ cnt = fscanf(config_file,"%u %u %u %u %u %u\n", &bit_rate,
+ &sync_seg, &prop_seg, &phase_seg1, &phase_seg2,
+ &sjw);
+ if (cnt != 6) {
+ fprintf(stderr,"Wrong data format in line %d in %s\n",
+ line, CONFIG_FILE_NAME);
+ exit(EXIT_FAILURE);
+ }
+ line ++;
+ tweak_a_bitrate(bit_rate, sync_seg, prop_seg, phase_seg1,
+ phase_seg2, sjw);
+ }
+
+ fclose(config_file);
+
exit(EXIT_SUCCESS);
}
+static void cmd_tweak(int argc, char *argv[])
+{
+ if (argc < 4)
+ tweak_from_config_file(argc, argv);
+ else {
+ if (argc < 9)
+ help();
+ tweak_from_command_line(argc, argv);
+ }
+}
#if 0
static void do_show_state(int argc, char *argv[])
@@ -189,14 +292,14 @@ int main(int argc, char *argv[])
{
if ((argc < 2) || !strcmp(argv[1], "--help"))
help();
-
+#if 0
if ((s = socket(AF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
perror("socket");
exit(EXIT_FAILURE);
}
strncpy(ifr.ifr_name, argv[1], IFNAMSIZ);
-
+#endif
if (argc < 3)
cmd_show_interface(argc, argv);
@@ -204,6 +307,9 @@ int main(int argc, char *argv[])
cmd_baudrate(argc, argv);
if (!strcmp(argv[2], "mode"))
cmd_mode(argc, argv);
+ if (!strcmp(argv[2], "tweak"))
+ cmd_tweak(argc, argv);
+
/* if (!strcmp(argv[2], "state")) */
/* cmd_state(argc, argv); */