/* 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; }
int can_GetStat( struct inode *inode, CanStatusPar_t *stat ) { unsigned int board = MINOR(inode->i_rdev); msg_fifo_t *Fifo; unsigned long flags; stat->type = CAN_TYPE_FlexCAN; stat->baud = Baud[board]; /* printk(" STAT ST 0x%x\n", CANin(board, canstat)); */ stat->status = CANinw(board, estat); /* not available in the FlexCAN, lets fill 127 here */ stat->error_warning_limit = 127; stat->rx_errors = CANin(board, rxectr); stat->tx_errors = CANin(board, txectr); /* error code is not available, use estat again */ stat->error_code= CANinw(board, estat); /* Collect information about the RX and TX buffer usage */ /* Disable CAN Interrupts */ /* !!!!!!!!!!!!!!!!!!!!! */ save_flags(flags); cli(); Fifo = &Rx_Buf[board]; stat->rx_buffer_size = MAX_BUFSIZE; /**< size of rx buffer */ /* number of messages */ stat->rx_buffer_used = (Fifo->head < Fifo->tail) ? (MAX_BUFSIZE - Fifo->tail + Fifo->head) : (Fifo->head - Fifo->tail); Fifo = &Tx_Buf[board]; stat->tx_buffer_size = MAX_BUFSIZE; /* size of tx buffer */ /* number of messages */ stat->tx_buffer_used = (Fifo->head < Fifo->tail) ? (MAX_BUFSIZE - Fifo->tail + Fifo->head) : (Fifo->head - Fifo->tail); /* Enable CAN Interrupts */ /* !!!!!!!!!!!!!!!!!!!!! */ restore_flags(flags); 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); }