/* change the bit timings of the selected CAN channel */ int CAN_SetTiming (int board, int baud) { /* int custom=0; */ BTR_TAB_TOUCAN_T * table = (BTR_TAB_TOUCAN_T*)can_btr_tab_toucan; DBGin("CAN_SetTiming"); DBGprint(DBG_DATA, ("baud[%d]=%d", board, baud)); /* enable changing of bit timings */ CANsetw(board, canmcr, CAN_MCR_HALT); /* search for data from table */ while(1) { if (table->rate == 0 || table->rate == baud) { break; } table++; } if (table->rate == 0) { /* try to use baud as custom specific bit rate * not implemented yet */ return -ENXIO; } /* * Set Timing Register values. * Initialize the bit timing parameters PROPSEG, PSEG1, PSEG2 and RJW * in control registers 1 and 2. * * The FlexCAN module uses three 8-bit registers to set-up * the bit timing parameters required by the CAN protocol. * Control registers 1 and 2 contain the PROPSEG, PSEG1, PSEG2 * and RJW fields which allow the user to configure * the bit timing parameters. * The prescaler divide register (PRESDIV) allows the user to select * the ratio used to derive the S-Clock from the system clock. * The time quanta clock operates at the S-clock frequency. */ CANout(board, presdiv, table->presdiv); CANout(board, canctrl2, ((table->pseg1 << 3)+ table->pseg2)); CANout(board, canctrl1, ( 0 /* SAMP = 0 , 0/0x80 */ + 0 /* LOOP = 0 , 0/0x40 */ + 0 /* TSYNC= 0 , 0/0x20 */ + 0 /* LBUF = 0 , 0/0x10 */ + 0 /* RSVD = 0 , 0/0x08 */ + table->propseg) ); /* * Stay in configuration mode; a call to Start-CAN() is necessary to * activate the CAN controller with the new bit rate */ DBGprint(DBG_DATA,("canctrl2=0x%x presdiv=0x%x", CANin(board, canctrl2), CANin(board, presdiv)) ); DBGout(); return 0; }
//reset the CAN device void reset_ADV_PCI(int dev) { unsigned char temp; #ifdef CAN_DEBUG printk("Enter can_reset, device = %d\n", dev); #endif if (dev < 0 || dev>= MAX_CHANNELS ) { #ifdef CAN_DEBUG printk( "in can_get_reg function the device=%d is error!\n", dev); #endif return; } temp = CANin(dev, canmode ); CANout(dev, canmode, temp|0x01 ); udelay(10000); }
/* * CAN_ChipReset - performs the first initialization or re-iniatalization of the chip * * set INIT mode * initialize the I/O pin modes as CAN TX/RX * initialize the CAN bit timing * initialize message buffers * initialize interrut sources */ int CAN_ChipReset (int board) { int i; DBGin("CAN_ChipReset"); /* printk("CAN_ChipReset\n"); */ /* * Initialize Port AS PAR to have Can TX/RX signals enabled */ #define MCF5282_GPIO_PASPAR (*(volatile u16 *)(void *)(0x40100056)) MCF5282_GPIO_PASPAR = 0x0FF0; /* printk("I/O %p %04x\n", (volatile u16 *)(void *)(0x40100056), MCF5282_GPIO_PASPAR); */ /* * go to INIT mode * Any configuration change/initialization requires that the FlexCAN be * frozen by either asserting the HALT bit in the * module configuration register or by reset. * For Init_CAN() we choose reset. */ CANresetw(board, canmcr, CAN_MCR_FRZ); /* CANoutw(board, canmcr, 0x0080); */ CANsetw(board, canmcr, CAN_MCR_SOFT_RST); udelay(10); /* Test Reset Status */ if(CANtestw(board, canmcr, CAN_MCR_SOFT_RST) != 0) { MOD_DEC_USE_COUNT; DBGout();return -1; } udelay(10); /* Initialize the transmit and receive pin modes in control register 0 */ CANout(board, canctrl0, CAN_CTRL0_DISABLE_BOFF_INT /* disable Bus-Off Interrupt */ + CAN_CTRL0_DISABLE_ERR_INT /* disable Error Interrupt */ + 0 /* 4 , logic RX level */ + 0 /* 1 , logic TX level */ ); /* CANresetw(board, canmcr, CAN_MCR_HALT); */ CAN_SetTiming(board, Baud[board]); /* * Select the internal arbitration mode * LBUF in CANCTRL1 * LBUF Lowest Buffer Transmitted First * The LBUF bit defines the transmit-first scheme. * 0 = Message buffer with lowest ID is transmitted first. * 1 = Lowest numbered buffer ist transmitted first. * * should have no impact here, the driver is using only one * TX object * * !! change the order of the next two statements !! */ CANset(board, canctrl1, CAN_CTRL1_LBUF); CANreset(board, canctrl1, CAN_CTRL1_LBUF); /* * Initialize message buffers. * The control/status word of all message buffers are written * as an inactive receive message buffer. */ for(i = 0; i < 16; i++) { CAN_WRITE_CTRL(i, REC_CODE_NOT_ACTIVE, 0); } /* create a transmit object, that can be used for all kinds of messages */ /* some receive objects * - RECEIVE_STD_OBJ to receive all standard frames * - RECEIVE_EXT_OBJ to receive all extended frames * - ?? */ CAN_WRITE_CTRL(RECEIVE_STD_OBJ, REC_CODE_NOT_ACTIVE, 0); CAN_WRITE_OID(RECEIVE_STD_OBJ, 0); /* set IDE - extended bit to zero */ CAN_SetMask (board, AccCode[board], AccMask[board] ); CAN_WRITE_CTRL(RECEIVE_STD_OBJ, REC_CODE_EMPTY, 8); /* The IDE-Bit (Bit 4) must be set to 1 for extended */ CAN_WRITE_CTRL(RECEIVE_EXT_OBJ, REC_CODE_NOT_ACTIVE, 0); CAN_WRITE_XOID(RECEIVE_EXT_OBJ, 0); /* set IDE - extended bit to 1 */ CAN_SetMask (board, AccCode[board], AccMask[board] ); CAN_WRITE_CTRL(RECEIVE_EXT_OBJ, REC_CODE_EMPTY, 8); #if 0 /* RTR Receive Object !!! No such thing possible !!! */ CAN_WRITE_CTRL(RECEIVE_RTR_OBJ, REC_CODE_NOT_ACTIVE, 0); CAN_WRITE_OID(RECEIVE_RTR_OBJ, 1); CAN_SetMask (board, AccCode[board], AccMask[board] ); CAN_WRITE_CTRL(RECEIVE_RTR_OBJ, REC_CODE_EMPTY, 8); #endif /* CAN_register_dump(); */ /* CAN_object_dump(RECEIVE_STD_OBJ); */ /* CAN_object_dump(RECEIVE_EXT_OBJ); */ /* CAN_object_dump(RECEIVE_RTR_OBJ); */ /* * - Initialize IARB[3:0] to a non zero value in CANMCR * ( This is done in CAN-ChipReset() ) * - Set the required mask bits in the IMASK register (for all message * buffer interrupts) in CANCTRL0 for bus off and error interrupts, * and in CANMCR for WAKE interrupt. */ /* dont't forget error int's ! */ CANsetw(board, canmcr, 1); CANoutw(board, imask, (1 << RECEIVE_STD_OBJ) +(1 << RECEIVE_EXT_OBJ) +(1 << TRANSMIT_OBJ)); /* printk("imask at %p \n", &((canregs_t *)can_base[board])->imask ); */ /* CAN_register_dump(); */ DBGout(); return 0; }