From 7eca1ac39aa9f2a65ba0607d55f7155f5a56ad15 Mon Sep 17 00:00:00 2001 From: ppisa Date: Wed, 1 Jun 2005 03:58:45 +0000 Subject: [PATCH] Changes to prepare work area for C_CAN testing and rethinking Neil Bryan from embebidos.com works on C_CAN support and he has contributed or initiated most of these changes. There seems to be more problems to solve proper locking yet. --- lincan/include/c_can.h | 108 +++++++++++++++++++++--------------- lincan/include/main.h | 2 +- lincan/src/Makefile.omk | 11 +++- lincan/src/boardlist.c | 8 +++ lincan/src/c_can.c | 57 +++++++++++++++---- lincan/src/c_can_irq.c | 2 +- lincan/src/close.c | 1 - lincan/src/hms30c7202_can.c | 18 ++++-- lincan/src/ioctl.c | 1 - lincan/src/main.c | 9 ++- lincan/src/open.c | 1 - 11 files changed, 148 insertions(+), 70 deletions(-) diff --git a/lincan/include/c_can.h b/lincan/include/c_can.h index 1c3bb8f..b68bea0 100644 --- a/lincan/include/c_can.h +++ b/lincan/include/c_can.h @@ -68,51 +68,69 @@ int c_can_register(struct chipspecops_t *chipspecops); 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 diff --git a/lincan/include/main.h b/lincan/include/main.h index be2534b..e05e774 100644 --- a/lincan/include/main.h +++ b/lincan/include/main.h @@ -74,7 +74,7 @@ struct candevice_t { 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; diff --git a/lincan/src/Makefile.omk b/lincan/src/Makefile.omk index 375eda3..8280b8b 100644 --- a/lincan/src/Makefile.omk +++ b/lincan/src/Makefile.omk @@ -2,15 +2,17 @@ lincan_cards_NAMES = pip pccan smartcan nsi cc_can104 ems_cpcpci \ 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) @@ -26,6 +28,11 @@ ifeq ($(CONFIG_OC_LINCAN_CARD_unican),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 diff --git a/lincan/src/boardlist.c b/lincan/src/boardlist.c index 590341b..739f30e 100644 --- a/lincan/src/boardlist.c +++ b/lincan/src/boardlist.c @@ -37,6 +37,8 @@ extern int unican_vme_register(struct hwspecops_t *hwspecops); 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 @@ -121,6 +123,12 @@ const struct boardtype_t can_boardtypes[]={ #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} }; diff --git a/lincan/src/c_can.c b/lincan/src/c_can.c index 0efc91f..e51181b 100644 --- a/lincan/src/c_can.c +++ b/lincan/src/c_can.c @@ -215,8 +215,6 @@ int c_can_baud_rate(struct canchip_t *pchip, int rate, int clock, 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++) { @@ -237,7 +235,7 @@ int c_can_baud_rate(struct canchip_t *pchip, int rate, int clock, 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; @@ -467,11 +465,6 @@ int c_can_config_irqs(struct canchip_t *pchip, 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); @@ -704,11 +697,10 @@ int c_can_start_chip(struct canchip_t *pchip) 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 @@ -735,8 +727,10 @@ int c_can_stop_chip(struct canchip_t *pchip) 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; @@ -820,8 +814,10 @@ void c_can_registerdump(struct canchip_t *pchip) (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", @@ -884,6 +880,37 @@ void c_can_registerdump(struct canchip_t *pchip) 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) @@ -916,7 +943,13 @@ 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; } diff --git a/lincan/src/c_can_irq.c b/lincan/src/c_can_irq.c index eb03ac8..7c93901 100644 --- a/lincan/src/c_can_irq.c +++ b/lincan/src/c_can_irq.c @@ -214,7 +214,7 @@ void c_can_irq_sync_activities(struct canchip_t *chip, struct msgobj_t *obj) // 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; diff --git a/lincan/src/close.c b/lincan/src/close.c index d07d52a..e39b3b1 100644 --- a/lincan/src/close.c +++ b/lincan/src/close.c @@ -11,7 +11,6 @@ #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" diff --git a/lincan/src/hms30c7202_can.c b/lincan/src/hms30c7202_can.c index df21d2d..1a18904 100644 --- a/lincan/src/hms30c7202_can.c +++ b/lincan/src/hms30c7202_can.c @@ -301,7 +301,7 @@ int hms30c7202_init_chip_data(struct candevice_t *candev, int chipnr) 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; @@ -345,8 +345,9 @@ int hms30c7202_init_obj_data(struct canchip_t *chip, int objnr) * @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 */ @@ -355,6 +356,9 @@ void hms30c7202_write_register(unsigned data, unsigned long address) { 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); @@ -368,8 +372,9 @@ void hms30c7202_write_register(unsigned data, unsigned long 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 */ @@ -377,6 +382,9 @@ unsigned hms30c7202_read_register(unsigned long address) { 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); diff --git a/lincan/src/ioctl.c b/lincan/src/ioctl.c index 38d75a4..43535d0 100644 --- a/lincan/src/ioctl.c +++ b/lincan/src/ioctl.c @@ -11,7 +11,6 @@ #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) { diff --git a/lincan/src/main.c b/lincan/src/main.c index 9928c15..bb6abbf 100644 --- a/lincan/src/main.c +++ b/lincan/src/main.c @@ -211,7 +211,7 @@ int init_module(void) for (i=0; inr_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; } @@ -247,7 +247,9 @@ int init_module(void) #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