X-Git-Url: http://rtime.felk.cvut.cz/gitweb/lincan.git/blobdiff_plain/4aae63139869c3eb9150a3fd49ff682084e2072d..cb551cc1582f3b51cf17e80730bee3c2f0701c3f:/lincan/include/c_can.h diff --git a/lincan/include/c_can.h b/lincan/include/c_can.h new file mode 100644 index 0000000..4955d86 --- /dev/null +++ b/lincan/include/c_can.h @@ -0,0 +1,247 @@ +/* c_can.h - Hynix HMS30c7202 ARM generic C_CAN module handling + * Linux CAN-bus device driver. + * Written by Sebastian Stolzenberg email:stolzi@sebastian-stolzenberg.de + * Based on code from Arnaud Westenberg email:arnaud@wanadoo.nl + * and Ake Hedman, eurosource, akhe@eurosource.se + * Rewritten for new CAN queues by Pavel Pisa - OCERA team member + * email:pisa@cmp.felk.cvut.cz + * This software is released under the GPL-License. + * Version lincan-0.2 9 Jul 2003 + */ + +void hms30c7202_write_reg_w(const struct chip_t *pchip, u16 data, unsigned reg); + +u16 hms30c7202_read_reg_w(const struct chip_t *pchip, unsigned reg); + +#ifndef CONFIG_OC_LINCAN_DYNAMICIO +/* + * optimized inline version, may it be, that it can be too fast for the chip + */ +extern inline void c_can_write_reg_w(const struct chip_t *pchip, u16 data, unsigned reg) +{ + u32 address = pchip->chip_base_addr + reg; + writew(data,address); +} + +extern inline u16 c_can_read_reg_w(const struct chip_t *pchip, unsigned reg) +{ + u32 address = pchip->chip_base_addr + reg; + return readw(address); +} +#else /*CONFIG_OC_LINCAN_DYNAMICIO*/ +/* + * the standard routines for register access cannot be used, + * because they work only with 8-bit peripherals + */ + +extern inline void c_can_write_reg_w(const struct chip_t *pchip, u16 data, unsigned reg) +{ + hms30c7202_write_reg_w(pchip, data, reg); +} + +extern inline u16 c_can_read_reg_w(const struct chip_t *pchip, unsigned reg) +{ + return hms30c7202_read_reg_w(pchip, reg); +} +#endif /*CONFIG_OC_LINCAN_DYNAMICIO*/ + +extern can_spinlock_t c_can_spwlock; // Spin lock for write operations +extern can_spinlock_t c_can_sprlock; // Spin lock for read operations +extern can_spinlock_t c_can_if1lock; // spin lock for the if1 register +extern can_spinlock_t c_can_if2lock; // spin lcok for the if2 register + +int c_can_if1_busycheck(struct chip_t *pchip); +int c_can_if2_busycheck(struct chip_t *pchip); + +int c_can_enable_configuration(struct chip_t *pchip); +int c_can_disable_configuration(struct chip_t *pchip); +int c_can_chip_config(struct chip_t *pchip); +int c_can_baud_rate(struct chip_t *chip, int rate, int clock, + int sjw, int sampl_pt, int flags); +int c_can_mask(struct msgobj_t *pmsgobj, + u32 mask, + u16 usedirbit); +int c_can_use_mask(struct msgobj_t *pmsgobj, + u16 useflag); +int c_can_clear_objects(struct chip_t *pchip); +int c_can_config_irqs(struct chip_t *pchip, + u16 irqs); +int c_can_pre_read_config(struct chip_t *chip, struct msgobj_t *obj); +int c_can_send_msg(struct chip_t *pchip, struct msgobj_t *pmsgobj, + struct canmsg_t *pmsg); +int c_can_remote_request(struct chip_t *pchip, struct msgobj_t *pmsgobj ); +int c_can_set_btregs(struct chip_t *chip, + u16 btr0, + u16 btr1); +int c_can_start_chip(struct chip_t *pchip); +int c_can_stop_chip(struct chip_t *pchip); +int c_can_check_tx_stat(struct chip_t *pchip); + +int c_can_register(struct chipspecops_t *chipspecops); + +void c_can_registerdump(struct chip_t *pchip); + +void c_can_irq_sync_activities(struct chip_t *chip, struct msgobj_t *obj); + +can_irqreturn_t c_can_irq_handler(int irq, void *dev_id, struct pt_regs *regs); + +/* 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 */ + +/* Control register */ +enum c_can_BASIC_CR +{ + CR_INIT = 1, // Internal Initialization Pending + CR_MIE = 1<<1, // Module Interrupt Enable + CR_SIE = 1<<2, // Status-change Interrupt Enable + CR_EIE = 1<<3, // Error Interrupt Enable + CR_DAR = 1<<5, // Disable Automatic Retransmission + CR_CCE = 1<<6, // Configuration Change Enable + CR_TEST = 1<<7 // Test Mode Enable +}; + +/* Status Register */ +enum c_can_BASIC_SR +{ + SR_TXOK = 1<<3, // Transmitted a Message Successfully + SR_RXOK = 1<<4, // Received a Message Successfully + SR_EPASS = 1<<5, // Error Passive + SR_EWARN = 1<<6, // Error Warning Status + SR_BOFF = 1<<7, // Bus Off Status +}; + +/* Status Register Last Error Codes */ +enum c_can_BASIC_SRLEC +{ + SRLEC_NE = 0, // Last Error Code: No Error + SRLEC_SE = 1, // LEC: Stuff Error + SRLEC_FE = 2, // LEC: Form Error + SRLEC_AE = 3, // LEC: Acknowledgement Error + SRLEC_B1 = 4, // LEC: Bit1 Error + SRLEC_B0 = 5, // LEC: Bit0 Error + SRLEC_CR = 6 // LEC: CRC Error +}; + +/* Error Counting Register */ +enum c_can_BASIC_EC +{ + EC_REP = 1<<15 // Receive Error Passive +}; + +/* Interrupt Register */ +enum c_can_BASIC_INT +{ + INT_NOINT = 0, // No Interrupt is pending + INT_STAT = 0x8000 // Status Interrupt +}; + +/* CAN Test Register */ +enum c_can_BASIC_TR +{ + TR_BASIC = 1<<2, // Basic Mode + TR_SLNT = 1<<3, // Silent Mode + TR_LOOPB = 1<<4, // Loop Back Mode + TR_RX = 1<<7 // Receive (CAN_RX Pin) +}; + +/* CAN Test Register TX Control*/ +enum c_can_BASIC_TRTX +{ + TRTX_RST = 0, // Reset value, CAN_TX is controlled by the CAN Core + TRTX_MON = 1, // Sample Point can be monitored at CAN_TX pin + TRTX_DOM = 2, // CAN_TX pin drives a dominant('0') value + TRTX_REC = 3 // CAN_TX pin drives a recessive('1') value +}; + +/* CAN Enable Register */ +enum c_can_BASIC_CE +{ + CE_EN = 1 // CAN Enable Bit +}; + +/* Interface X Command Request Register */ +enum c_can_BASIC_IFXCR +{ + IFXCR_BUSY = 1<<15 // Busy Flag (Write Access only when Busy='0') +}; + +/* Interface X Command Mask Register */ +enum c_can_BASIC_IFXCM +{ + IFXCM_DB = 1, // R/W Data Byte 4-7 + IFXCM_DA = 1<<1, // R/W Data Byte 0-3 + IFXCM_TRND = 1<<2, // Transmit Request (WRRD=1) or Reset New Date Bit (WRRD=0) + IFXCM_CLRINTPND = 1<<3, // Clear Interrupt Pending Bit when reading the Message Object + IFXCM_CNTRL = 1<<4, // Access Interface X Message Control Bits + IFXCM_ARB = 1<<5, // Access Interface X Arbitration + IFXCM_MASK = 1<<6, // Access Interface X Mask Bits + IFXCM_WRRD = 1<<7 // Read/Write (write data from Interface Registers to Message Object if ='1') + // (read data from Message Object to Interface Registers if ='0') +}; + +/* Interface X Mask 2 Register */ +enum c_can_BASIC_IFXMSK2 +{ + IFXMSK2_MDIR = 1<<14, // Mask Message Direction (message direction bit(RTR) used for acceptance filt. or not) + IFXMSK2_MXTD = 1<<15 // Mask Extended Identifier (extended id bit(IDE) used for acceptance filt. or not) +}; + +/* Interface X Arbitration 2 Register */ +enum c_can_BASIC_IFXARB2 +{ + IFXARB2_DIR = 1<<13, // Message Direction (transmit='1') + IFXARB2_XTD = 1<<14, // Use Extended Identifier + IFXARB2_MVAL = 1<<15 // Message Validation +}; + +/* Interface X Message Control Register */ +enum c_can_BASIC_IFXMC +{ + IFXMC_EOB = 1<<7, // End of Buffer (marks last Message Object of FIFO Buffer) + IFXMC_TXRQST = 1<<8, // Transmit Request + IFXMC_RMTEN = 1<<9, // Remote Enable + IFXMC_RXIE = 1<<10, // Receive Interrupt Enable + IFXMC_TXIE = 1<<11, // Transmit Interrupt Enable + IFXMC_UMASK = 1<<12, // Use Identifier Mask + IFXMC_INTPND = 1<<13, // Interrupt Pending + IFXMC_MSGLST = 1<<14, // Message Lost (Only valid for direction = receive) + IFXMC_NEWDAT = 1<<15 // New Data +}; +