void c_can_registerdump(struct canchip_t *pchip);
-void c_can_irq_sync_activities(struct canchip_t *chip, struct msgobj_t *obj);
-
-int c_can_irq_handler(int irq, struct canchip_t *chip);
-
-int c_can_fill_chipspecops(struct canchip_t *chip);
-
-/* BasicCAN mode address map */
-#define CCCR 0x0000 /* Control Register */
-#define CCSR 0x0004 /* Status Register */
-#define CCEC 0x0008 /* Error Counting Register */
-#define CCBT 0x000C /* Bit Timing Register */
-#define CCINTR 0x0010 /* Interrupt Register */
-#define CCTR 0x0014 /* Test Register */
-#define CCBRPE 0x0018 /* Baud Rate Prescaler Extension Register */
-#define CCCE 0x001C /* CAN Enable Register */
-#define CCTREQ1 0x0100 /* Transmission Request 1 Register */
-#define CCTREQ2 0x0104 /* Transmission Request 2 Register */
-#define CCND1 0x0120 /* New Data 1 Register */
-#define CCND2 0x0124 /* New Data 2 Register */
-#define CCINTP1 0x0140 /* Interrupt Pending 1 Register */
-#define CCINTP2 0x0144 /* Interrupt Pending 2 Register */
-
-#define CCIF1CR 0x0020 /* Interface 1 Command Request Register */
-#define CCIF1CM 0x0024 /* IF1 Command Mask Register */
-#define CCIF1M1 0x0028 /* IF1 Mask 1 Register */
-#define CCIF1M2 0x002C /* IF1 Mask 2 Register */
-#define CCIF1A1 0x0030 /* IF1 Arbitration 1 Register */
-#define CCIF1A2 0x0034 /* IF1 Arbitration 2 Register */
-#define CCIF1DMC 0x0038 /* IF1 Message Control Register */
-#define CCIF1DA1 0x003C /* IF1 Data A 1 Register */
-#define CCIF1DA2 0x0040 /* IF1 Data A 2 Register */
-#define CCIF1DB1 0x0044 /* IF1 Data B 1 Register */
-#define CCIF1DB2 0x0048 /* IF1 Data B 2 Register */
-
-#define CCIF2CR 0x0080 /* Interface 2 Command Request Register */
-#define CCIF2CM 0x0084 /* IF2 Command Mask Register */
-#define CCIF2M1 0x0088 /* IF2 Mask 1 Register */
-#define CCIF2M2 0x008C /* IF2 Mask 2 Register */
-#define CCIF2A1 0x0090 /* IF2 Arbitration 1 Register */
-#define CCIF2A2 0x0094 /* IF2 Arbitration 2 Register */
-#define CCIF2DMC 0x0098 /* IF2 Message Control Register */
-#define CCIF2DA1 0x009C /* IF2 Data A 1 Register */
-#define CCIF2DA2 0x00A0 /* IF2 Data A 2 Register */
-#define CCIF2DB1 0x00A4 /* IF2 Data B 1 Register */
-#define CCIF2DB2 0x00A8 /* IF2 Data B 2 Register */
+void c_can_if1_registerdump(struct canchip_t *pchip);
+
+void c_can_irq_sync_activities(struct canchip_t *pchip, struct msgobj_t *obj);
+
+int c_can_irq_handler(int irq, struct canchip_t *pchip);
+
+int c_can_fill_chipspecops(struct canchip_t *pchip);
+
+/* The CCCE register is not implemented in version 1.2 of C_CAN */
+#undef C_CAN_WITH_CCCE
+
+/* The mask of C_CAN registers offsets */
+#define C_CAN_REGOFFS_MASK 0xFF
+
+/* SSEE C_CAN Memory map */
+/* BasicCAN offsets are multiplied by two */
+#define CCCR 0x00 /* Control Register */
+#define CCSR 0x02 /* Status Register */
+#define CCEC 0x04 /* Error Counting Register */
+#define CCBT 0x06 /* Bit Timing Register */
+#define CCINTR 0x08 /* Interrupt Register */
+#define CCTR 0x0A /* Test Register */
+#define CCBRPE 0x0C /* Baud Rate Prescaler Extension Register */
+
+#ifdef C_CAN_WITH_CCCE
+#define CCCE 0x0E /* CAN Enable Register */
+#endif /*C_CAN_WITH_CCCE*/
+
+#define CCIF1CR 0x10 /* Interface 1 Command Request Register */
+#define CCIF1CM 0x12 /* IF1 Command Mask Register */
+#define CCIF1M1 0x14 /* IF1 Mask 1 Register */
+#define CCIF1M2 0x16 /* IF1 Mask 2 Register */
+#define CCIF1A1 0x18 /* IF1 Arbitration 1 Register */
+#define CCIF1A2 0x1A /* IF1 Arbitration 2 Register */
+#define CCIF1DMC 0x1C /* IF1 Message Control Register */
+#define CCIF1DA1 0x1E /* IF1 Data A 1 Register */
+#define CCIF1DA2 0x20 /* IF1 Data A 2 Register */
+#define CCIF1DB1 0x22 /* IF1 Data B 1 Register */
+#define CCIF1DB2 0x24 /* IF1 Data B 2 Register */
+
+#define CCIF2CR 0x40 /* Interface 2 Command Request Register */
+#define CCIF2CM 0x42 /* IF2 Command Mask Register */
+#define CCIF2M1 0x44 /* IF2 Mask 1 Register */
+#define CCIF2M2 0x46 /* IF2 Mask 2 Register */
+#define CCIF2A1 0x48 /* IF2 Arbitration 1 Register */
+#define CCIF2A2 0x4A /* IF2 Arbitration 2 Register */
+#define CCIF2DMC 0x4C /* IF2 Message Control Register */
+#define CCIF2DA1 0x4E /* IF2 Data A 1 Register */
+#define CCIF2DA2 0x50 /* IF2 Data A 2 Register */
+#define CCIF2DB1 0x52 /* IF2 Data B 1 Register */
+#define CCIF2DB2 0x54 /* IF2 Data B 2 Register */
+
+#define CCTREQ1 0x80 /* Transmission Request 1 Register */
+#define CCTREQ2 0x82 /* Transmission Request 2 Register */
+
+#define CCND1 0x90 /* New Data 1 Register */
+#define CCND2 0x92 /* New Data 2 Register */
+
+#define CCINTP1 0xA0 /* Interrupt Pending 1 Register */
+#define CCINTP2 0xA2 /* Interrupt Pending 2 Register */
+
+#define CCIMV1 0xB0 /* Message Valid 1 Register */
+#define CCIMV2 0xB2 /* Message Valid 2 Register */
/* Control register */
enum c_can_BASIC_CR
char *hwname; /* text board type */
int candev_idx; /* board index in canhardware_t.candevice[] */
unsigned long io_addr; /* IO/physical MEM address */
- unsigned long res_addr; /* optional seset register port */
+ unsigned long res_addr; /* optional reset register port */
unsigned long dev_base_addr; /* CPU translated IO/virtual MEM address */
unsigned int flags;
int nr_all_chips;
pc_i03 pcm3680 aim104 m437 pcccan ssv bfadcan pikronisa eb8245 \
kv_pcican msmcan oscar adlink7841 unican virtual template
+lincan_morecards_NAMES = hms30c7202_can ns_dev_can
+
default_CONFIG = CONFIG_OC_LINCAN=y CONFIG_OC_LINCANRTL=n CONFIG_OC_LINCANVME=n
default_CONFIG += CONFIG_OC_LINCAN_PORTIO_ONLY=n CONFIG_OC_LINCAN_MEMIO_ONLY=n
default_CONFIG += $(foreach n, $(lincan_cards_NAMES), CONFIG_OC_LINCAN_CARD_$(n)=y)
+default_CONFIG += $(foreach n, $(lincan_morecards_NAMES), CONFIG_OC_LINCAN_CARD_$(n)=n)
-lincan_cards_SELECTED = $(filter %.y, $(foreach x, $(lincan_cards_NAMES), $(x).$(CONFIG_OC_LINCAN_CARD_$(x))))
+lincan_cards_SELECTED = $(filter %.y, $(foreach x, $(lincan_cards_NAMES) $(lincan_morecards_NAMES), $(x).$(CONFIG_OC_LINCAN_CARD_$(x))))
lincan_cards_SELECTED := $(lincan_cards_SELECTED:%.y=%)
-
LOCAL_CONFIG_H = lincan_config.h
ifeq ($(CONFIG_OC_LINCAN),y)
lincan_cards_SOURCES += unican_cl2.c
endif
+ifneq ($(filter hms30c7202_can ns_dev_can,$(lincan_cards_SELECTED)),)
+$(warning Not finished C_CAN support requested)
+lincan_cards_SOURCES += c_can.c c_can_irq.c
+endif
+
ifneq ($(CONFIG_OC_LINCANRTL),y)
kernel_MODULES = lincan
extern int pcan_dongle_register(struct hwspecops_t *hwspecops);
extern int eb8245_register(struct hwspecops_t *hwspecops);
extern int adlink7841_register(struct hwspecops_t *hwspecops);
+extern int ns_dev_register(struct hwspecops_t *hwspecops);
+extern int hms30c7202_register(struct hwspecops_t *hwspecops);
const struct boardtype_t can_boardtypes[]={
#ifdef CONFIG_OC_LINCAN_CARD_template
#endif
#if defined(CONFIG_OC_LINCAN_CARD_adlink7841)
{"adlink7841", adlink7841_register, 0},
+ #endif
+ #if defined(CONFIG_OC_LINCAN_CARD_ns_dev_can)
+ {"ns_dev", ns_dev_register, 1},
+ #endif
+ #if defined(CONFIG_OC_LINCAN_CARD_hms30c7202_can)
+ {"hms30c7202", hms30c7202_register, 1},
#endif
{NULL}
};
if (c_can_enable_configuration(pchip))
return -ENODEV;
- clock /=2;
-
/* tseg even = round down, odd = round up */
for (tseg=(0+0+2)*2; tseg<=(MAX_TSEG2+MAX_TSEG1+2)*2+1; tseg++)
{
if (best_error && (rate/best_error < 10))
{
CANMSG("baud rate %d is not possible with %d Hz clock\n",
- rate, 2*clock);
+ rate, clock);
CANMSG("%d bps. brp=%d, best_tseg=%d, tseg1=%d, tseg2=%d\n",
best_rate, best_brp, best_tseg, tseg1, tseg2);
return -EINVAL;
DEBUGMSG("(c%d)calling c_can_config_irqs(...)\n", pchip->chip_idx);
- /*
- CANMSG("c_can_config_irqs not implemented\n");
- return -ENOSYS;
- */
-
tempreg = c_can_read_reg_w(pchip, CCCR);
//DEBUGMSG("-> CAN Control Register: 0x%.4lx\n",(long)tempreg);
c_can_write_reg_w(pchip, tempreg | (irqs & 0xe), CCCR);
return -1;
}
- // flags = c_can_read_reg_w(pchip, CCCE) | CE_EN;
- // c_can_write_reg_w(pchip, flags, CCCE);
- //
+#ifdef C_CAN_WITH_CCCE
flags = c_can_read_reg_w(pchip, CCCE) | CE_EN;
c_can_write_reg_w(pchip, flags, CCCE);
+#endif
DEBUGMSG("-> ok\n");
#ifdef REGDUMP
return -1;
}
+#ifdef C_CAN_WITH_CCCE
flags = c_can_read_reg_w(pchip, CCCE) & ~CE_EN;
c_can_write_reg_w(pchip, flags, CCCE);
+#endif
DEBUGMSG("-> ok\n");
return 0;
(long)(c_can_read_reg_w( pchip, CCTR)));
CANMSG("Baud Rate Presc. Register: 0x%.4lx\n",
(long)(c_can_read_reg_w( pchip, CCBRPE)));
+#ifdef C_CAN_WITH_CCCE
CANMSG("CAN Enable Register: 0x%.4lx\n",
(long)(c_can_read_reg_w( pchip, CCCE)));
+#endif
CANMSG("Transm. Req. 1 Register: 0x%.4lx\n",
(long)(c_can_read_reg_w( pchip, CCTREQ1)));
CANMSG("Transm. Req. 2 Register: 0x%.4lx\n",
CANMSG("------------------------------------\n");
}
+
+void c_can_if1_registerdump(struct canchip_t *pchip)
+{
+ CANMSG("----------------------------------------\n");
+ CANMSG("Error Counting Register: 0x%.4lx\n",
+ (long)(c_can_read_reg_w( pchip, CCEC)));
+ CANMSG("---------C-CAN IF1 Register Dump--------\n");
+ CANMSG("IF1 Command Req. Register: 0x%.4lx\n",
+ (long)(c_can_read_reg_w( pchip, CCIF1CR)));
+ CANMSG("IF1 Command Mask Register: 0x%.4lx\n",
+ (long)(c_can_read_reg_w( pchip, CCIF1CM)));
+ CANMSG("IF1 Mask 1 Register: 0x%.4lx\n",
+ (long)(c_can_read_reg_w( pchip, CCIF1M1)));
+ CANMSG("IF1 Mask 2 Register: 0x%.4lx\n",
+ (long)(c_can_read_reg_w( pchip, CCIF1M2)));
+ CANMSG("IF1 Arbitration 1 Register: 0x%.4lx\n",
+ (long)(c_can_read_reg_w( pchip, CCIF1A1)));
+ CANMSG("IF1 Arbitration 2 Register: 0x%.4lx\n",
+ (long)(c_can_read_reg_w( pchip, CCIF1A2)));
+ CANMSG("IF1 Message Control Register: 0x%.4lx\n",
+ (long)(c_can_read_reg_w( pchip, CCIF1DMC)));
+ CANMSG("IF1 Data A1 Register: 0x%.4lx\n",
+ (long)(c_can_read_reg_w( pchip, CCIF1DA1)));
+ CANMSG("IF1 Data A2 Register: 0x%.4lx\n",
+ (long)(c_can_read_reg_w( pchip, CCIF1DA2)));
+ CANMSG("IF1 Data B1 Register: 0x%.4lx\n",
+ (long)(c_can_read_reg_w( pchip, CCIF1DB1)));
+ CANMSG("IF1 Data B2 Register: 0x%.4lx\n",
+ (long)(c_can_read_reg_w( pchip, CCIF1DB2)));
+}
+
///////////////////////////////////////////////////////////////////////
int c_can_register(struct chipspecops_t *chipspecops)
int c_can_fill_chipspecops(struct canchip_t *chip)
{
chip->chip_type="c_can";
- chip->max_objects = 32;
+ if(MAX_MSGOBJS >= 32) {
+ chip->max_objects = 32;
+ } else {
+ CANMSG("C_CAN requires 32 message objects per chip,"
+ " but only %d is compiled maximum\n",MAX_MSGOBJS);
+ chip->max_objects = MAX_MSGOBJS;
+ }
c_can_register(chip->chipspecops);
return 0;
}
// c_can_irq_handler
//
-int c_can_irq_handler(int irq, struct canchip_t *chip)
+int c_can_irq_handler(int irq, struct canchip_t *pchip)
{
struct rtr_id *rtr_search = hardware_p->rtr_queue;
u16 chip_status;
#include "../include/can_sysdep.h"
#include "../include/main.h"
#include "../include/close.h"
-#include "../include/i82527.h"
#include "../include/setup.h"
#include "../include/fasync.h"
candev->chip[chipnr]->chip_base_addr=candev->io_addr;
- candev->chip[chipnr]->clock = 16000000;
+ candev->chip[chipnr]->clock = 16000000/2;
/*candev->chip[chipnr]->int_clk_reg = 0x0;
candev->chip[chipnr]->int_bus_reg = 0x0;
* @address: memory address to write to
*
* The function hms30c7202_write_register() is used to write to hardware registers
- * on the CAN chip. You should only have to edit this function if your hardware
- * uses some specific write process.
+ * on the CAN chip. The registers are mapped on 32 bit bus on hms30c7202
+ * and thus registers span is twice as one defined by C_CAN manual and defines.
+ * This function compensates this difference.
* Return Value: The function does not return a value
* File: src/template.c
*/
{
int i;
//unsigned long usecs = 1;
+
+ address = ((address & C_CAN_REGOFFS_MASK) << 1) |
+ (address & ~C_CAN_REGOFFS_MASK);
//DEBUGMSG("Trying to write 0x%u16x to address 0x%lx\n",data,address);
* @address: memory address to read from
*
* The function hms30c7202_read_register() is used to read from hardware registers
- * on the CAN chip. You should only have to edit this function if your hardware
- * uses some specific read process.
+ * on the CAN chip. The registers are mapped on 32 bit bus on hms30c7202
+ * and thus registers span is twice as one defined by C_CAN manual and defines.
+ * This function compensates this difference.
* Return Value: The function returns the value stored in @address
* File: src/template.c
*/
{
u16 value, i;
+ address = ((address & C_CAN_REGOFFS_MASK) << 1) |
+ (address & ~C_CAN_REGOFFS_MASK);
+
//DEBUGMSG("Trying to read from address 0x%lx :",address);
value = readw(address);
#include "../include/can_sysdep.h"
#include "../include/main.h"
#include "../include/ioctl.h"
-#include "../include/i82527.h"
int can_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
for (i=0; i<hardware_p->nr_boards; i++) {
candev=hardware_p->candevice[i];
if (candev->hwspecops->request_io(candev))
- goto memory_error;
+ goto request_io_error;
candev->flags|=CANDEV_IO_RESERVED;
}
#ifdef CONFIG_DEVFS_FS
{
+ #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,50))
char dev_name[32];
+ #endif
int dev_minor;
for(i=0;i<MAX_TOT_MSGOBJS;i++) {
if(!objects_p[i]) continue;
goto memory_error;
reset_error: ;
+ CANMSG("Error resetting device.\n");
+ goto memory_error;
+
+ request_io_error: ;
+ CANMSG("Error to request IO resources for device.\n");
goto memory_error;
memory_error: ;
#include "../include/can_sysdep.h"
#include "../include/main.h"
#include "../include/open.h"
-#include "../include/i82527.h"
#include "../include/setup.h"
#define __NO_VERSION__