[U-Boot] [RFC 1/5] CAN interface library

Wolfgang Grandegger wg at grandegger.com
Sun Nov 1 12:33:33 CET 2009


From: Wolfgang Grandegger <wg at denx.de>

Signed-off-by: Wolfgang Grandegger <wg at denx.de>
---
 Makefile             |    1 +
 drivers/can/Makefile |   47 ++++++++++++++++++++++++++
 drivers/can/can.c    |   88 ++++++++++++++++++++++++++++++++++++++++++++++++++
 include/can.h        |   70 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 206 insertions(+), 0 deletions(-)
 create mode 100644 drivers/can/Makefile
 create mode 100644 drivers/can/can.c
 create mode 100644 include/can.h

diff --git a/Makefile b/Makefile
index bcb3fe9..dca15e0 100644
--- a/Makefile
+++ b/Makefile
@@ -203,6 +203,7 @@ LIBS += net/libnet.a
 LIBS += disk/libdisk.a
 LIBS += drivers/bios_emulator/libatibiosemu.a
 LIBS += drivers/block/libblock.a
+LIBS += drivers/can/libcan.a
 LIBS += drivers/dma/libdma.a
 LIBS += drivers/fpga/libfpga.a
 LIBS += drivers/gpio/libgpio.a
diff --git a/drivers/can/Makefile b/drivers/can/Makefile
new file mode 100644
index 0000000..74d2ff5
--- /dev/null
+++ b/drivers/can/Makefile
@@ -0,0 +1,47 @@
+#
+# Copyright 2000-2008
+# Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB 	:= $(obj)libcan.a
+
+COBJS-$(CONFIG_CAN)	+= can.o
+
+COBJS	:= $(COBJS-y)
+SRCS 	:= $(COBJS:.o=.c)
+OBJS 	:= $(addprefix $(obj),$(COBJS))
+
+all:	$(LIB)
+
+$(LIB):	$(obj).depend $(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
+
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+########################################################################
diff --git a/drivers/can/can.c b/drivers/can/can.c
new file mode 100644
index 0000000..c09bccf
--- /dev/null
+++ b/drivers/can/can.c
@@ -0,0 +1,88 @@
+/*
+ * (C) Copyright 2007-2009, Wolfgang Grandegger <wg at denx.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * CAN device interface library
+ */
+#include <common.h>
+#include <command.h>
+#include <can.h>
+
+static struct can_dev *can_devs;
+
+static char *baudrates[] = { "125K", "250K", "500K" };
+
+int can_register (struct can_dev* can_dev)
+{
+	struct can_dev* dev;
+
+	can_dev->next = NULL;
+	if (!can_devs)
+		can_devs = can_dev;
+	else {
+		for (dev = can_devs; dev->next; dev = dev->next)
+			    ;
+		dev->next = can_dev;
+	}
+
+	printf ("CAN: %s at %lx registered\n", can_dev->name, can_dev->base);
+
+	return 0;
+}
+
+struct can_dev *can_init (int dev_num, int ibaud)
+{
+	struct can_dev *dev;
+	int i;
+
+	if (!can_devs) {
+		puts ("No CAN devices registered\n");
+		return NULL;
+	}
+
+	/* Advance to selected device */
+	for (i = 0, dev = can_devs; dev; i++, dev = dev->next) {
+		if (i == dev_num)
+			break;
+	}
+
+	if (!dev) {
+		printf ("CAN device %d does not exist\n", dev_num);
+		return NULL;
+	}
+
+	printf ("Initializing CAN%d at 0x%08x with baudrate %s\n",
+		i, dev->base, baudrates[ibaud]);
+
+	dev->init (dev, ibaud);
+
+	return dev;
+}
+
+void can_list (void)
+{
+	struct can_dev *dev;
+	int i;
+
+	for (i = 0, dev = can_devs; dev; i++, dev = dev->next)
+		printf ("CAN%d: %s at 0x%p\n", i, dev->name, dev->base);
+}
diff --git a/include/can.h b/include/can.h
new file mode 100644
index 0000000..5f5c3c1
--- /dev/null
+++ b/include/can.h
@@ -0,0 +1,70 @@
+/*
+ * (C) Copyright 2007-2009, Wolfgang Grandegger <wg at denx.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __CAN_H__
+#define __CAN_H__
+
+#define CAN_XMIT_TIMEOUT_US 1000000
+
+#define CAN_EFF_MASK  0x1FFFFFFF
+#define CAN_SFF_MASK  0x000007FF
+
+#define CAN_EFF_FLAG  0x80000000
+#define CAN_RTR_FLAG  0x40000000
+
+struct can_msg {
+	u32 id;
+	u8  data[8];
+	u8  dlc;
+	u8  flags;
+};
+
+struct can_dev {
+	char *name;
+	unsigned long base;
+	int (*init) (struct can_dev *dev, unsigned int ibaud);
+	int (*xmit) (struct can_dev *dev, struct can_msg *msg);
+	int (*recv) (struct can_dev *dev, struct can_msg *msg);
+	int (*status) (struct can_dev *dev, int level);
+	struct can_dev *next;
+};
+
+static inline int can_status (struct can_dev *dev, int level)
+{
+	return dev->status (dev, level);
+}
+
+static inline int can_recv (struct can_dev *dev, struct can_msg *msg)
+{
+	return dev->recv (dev, msg);
+}
+
+static inline int can_xmit (struct can_dev *dev, struct can_msg *msg)
+{
+	return dev->xmit (dev, msg);
+}
+
+int can_register (struct can_dev* dev);
+struct can_dev *can_init (int dev_nr, int ibaud);
+void can_list (void);
+
+#endif /* __CAN_H__ */
-- 
1.6.2.5



More information about the U-Boot mailing list