⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 at9263funcs.c

📁 can4linux-3.5.3.gz can4 linux
💻 C
📖 第 1 页 / 共 3 页
字号:
		    rp->id =  oid;		    /* printk(" X = %d\n", ext); */		    ext = CAN_OBJ[RECEIVE_STD_OBJ].msr;		    rp->length = (ext & 0x000f0000) >> 16; 		    ext = (ext & CANBIT_MSR_MRTR) ? 1 : 0;		    /* printk(" DLC = %d %s\n", rp->length, ext ? "- RTR" : "");  */		    if(ext) {			rp->flags |= MSG_RTR;		    }		    rp->length =			(CAN_OBJ[RECEIVE_STD_OBJ].msr & 0x000f0000) >> 16; 		    /* Get data bytes		       FIXME:		       Don't take care of message length for now */		    data = CAN_OBJ[RECEIVE_STD_OBJ].mdl;		    rp->data[0] = (u8)data; 		    rp->data[1] = (u8)(data >>  8); 		    rp->data[2] = (u8)(data >> 16); 		    rp->data[3] = (u8)(data >> 24); 		    data = CAN_OBJ[RECEIVE_STD_OBJ].mdh;		    rp->data[4] = (u8)data; 		    rp->data[5] = (u8)(data >>  8); 		    rp->data[6] = (u8)(data >> 16); 		    rp->data[7] = (u8)(data >> 24); 		    RxFifo->status = BUF_OK;		    RxFifo->head = ++(RxFifo->head) % MAX_BUFSIZE;		    if(RxFifo->head == RxFifo->tail) {			printk(KERN_WARNING "CAN[%d] RX: FIFO overrun\n",						minor);			RxFifo->status = BUF_OVERRUN;		    }		    /*---------- kick the select() call  -*/		    /* This function will wake up all processes		       that are waiting on this event queue,		       that are in interruptible sleep		    */		    wake_up_interruptible(&CanWait[minor][rx_fifo]); 		    /* check for CAN controller overrun */		}	    }	    /* reset interrupt condition of this object */	    CAN_OBJ[RECEIVE_STD_OBJ].mcr = CANBIT_MCR_MTCR;	}	/*========== transmit interrupt */	/*=============================*/	if(sr & (1 << TRANSMIT_OBJ)) {	    /* CAN frame successfully sent */	    canmsg_t *tp = &TxFifo->data[TxFifo->tail];	    /* use time stamp sampled with last INT */	    last_Tx_object[minor].timestamp = timestamp;	    /* depending on the number of open processes	     * the TX data has to be copied in different	     * rx fifos	     */	    for(rx_fifo = 0; rx_fifo < CAN_MAX_OPEN; rx_fifo++) {		/* for every rx fifo */		if (CanWaitFlag[minor][rx_fifo] == 1) {		    /* this FIFO is in use */					    /*		     * Don't copy the message in the receive queue		     * of the process that sent the message unless		     * this process requested selfreception.		     */		    if ((last_Tx_object[minor].cob == rx_fifo) && 			(selfreception[minor][rx_fifo] == 0))		    {			continue;		    }		    /* prepare buffer to be used */		    RxFifo = &Rx_Buf[minor][rx_fifo];		    memcpy(  			(void *)&RxFifo->data[RxFifo->head],			(void *)&last_Tx_object[minor],			sizeof(canmsg_t));		    		    /* Mark message as 'self sent/received' */		    RxFifo->data[RxFifo->head].flags |= MSG_SELF;		    /* increment write index */		    RxFifo->status = BUF_OK;		    RxFifo->head = ++(RxFifo->head) % MAX_BUFSIZE;		    if(RxFifo->head == RxFifo->tail) {			printk("CAN[%d][%d] RX: FIFO overrun\n", minor, rx_fifo);			RxFifo->status = BUF_OVERRUN;		    } 		    /*---------- kick the select() call  -*/		    /* This function will wake up all processes		       that are waiting on this event queue,		       that are in interruptible sleep		    */		    wake_up_interruptible(&CanWait[minor][rx_fifo]); 		} /* this FIFO is in use */	    } /* end for loop filling all rx-fifos */	    /* Reset Interrupt Flag of transmit object	     * mailbox mode register */	    CAN_OBJ[TRANSMIT_OBJ].mmr = 0;	    if( TxFifo->free[TxFifo->tail] == BUF_EMPTY ) {		/* TX FIFO empty, nothing more to sent */		/* printk("TXE\n"); */		TxFifo->status = BUF_EMPTY;		TxFifo->active = 0;		/* This function will wake up all processes		   that are waiting on this event queue,		   that are in interruptible sleep		*/		wake_up_interruptible(&CanOutWait[minor]); 		goto Tx_done;	    }	    /* enter critical section */	    local_irq_save(iflags);	    /* The TX message FIFO contains other CAN frames to be sent	     * The next frame in the FIFO is copied into the last_Tx_object	     * and directly into the hardware of the CAN controller	     */	    /* The TX message FIFO contains other CAN frames to be sent	     * The next frame in the FIFO is copied into the last_Tx_object	     * and directly into the hardware of the CAN controller	     */	    memcpy(		    (void *)&last_Tx_object[minor],		    (void *)&TxFifo->data[TxFifo->tail],		    sizeof(canmsg_t));	    /*	      To prevent concurrent access with the internal CAN core,	      the application must disable the mailbox before writing to	      CAN_MIDx registers.	     */	    CAN_OBJ[TRANSMIT_OBJ].mmr = 0;	    /* fill the frame info and identifier fields , ID-Low and ID-High */	    if(tp->flags & MSG_EXT) {		/* use ID in extended message format */		CAN_WRITE_XOID(TRANSMIT_OBJ, tp->id);	    } else {		CAN_WRITE_OID(TRANSMIT_OBJ, tp->id);	    }	    /* - fill data -------------------------------------------------- */	    /* FIXME:	       Don't take care of message length for now */	    CAN_OBJ[TRANSMIT_OBJ].mdl = 			   tp->data[0]			+ (tp->data[1] <<  8)			+ (tp->data[2] << 16)			+ (tp->data[3] << 24);	    CAN_OBJ[TRANSMIT_OBJ].mdh = 			   tp->data[4]			+ (tp->data[5] <<  8)			+ (tp->data[6] << 16)			+ (tp->data[7] << 24);	   /* - /end -------------------------------------------------------- */	    if( tp->flags & MSG_RTR) {	    } else {	    }	    /* Enable transmit mail box */	    CAN_OBJ[TRANSMIT_OBJ].mmr = CANBIT_MMR_MOT_TX;	    /* Writing data length code,	       set transmit request 	    */	    CAN_OBJ[TRANSMIT_OBJ].mcr =		(tp->length << CANBIT_MCR_MDLC_POS)		 + ((tp->flags & MSG_RTR) ? CANBIT_MCR_MRTR : 0ul)		 + CANBIT_MCR_MTCR;	    /* now this entry is EMPTY */	    TxFifo->free[TxFifo->tail] = BUF_EMPTY;	    TxFifo->tail = ++(TxFifo->tail) % MAX_BUFSIZE;	    local_irq_restore(iflags);	    Tx_done:		;	}  /* Tx ISR */	/*=========== status interrupt */	/*=============================*/	/* take care of:	 * in Error Passive State, also ERRA bit is set	 */	if(sr & (		    CANBIT_SR_BOFF		  + CANBIT_SR_ERRA		  + CANBIT_SR_ERRP )) {	    	    int status_changed = 0;	    char *m = NULL;    /* printk(">> state = %d, status_changed %d\n", state, status_changed  ); */	    if(sr & CANBIT_SR_BOFF) {	    	m = "BusOFF";	    	sr &= ~CANBIT_SR_BOFF;	/* reset error passive bit */		/* Bus-Off: disable the Controller		   - the user has to call Start_CAN() */		CANoutl(minor, mode, CANBIT_MR_CANDIS);		/* disable the IRQ.	         * If no Busoff, we enable the IRQ again.	         */		CANoutl(minor, idr, CANBIT_IR_BOFF);		errorints++;	    	if(state != busoff); {		    /* printk(" CAN_Status %s Interrupt(%d)\n", m, errorints); */		    state = busoff;		    fflags = MSG_BUSOFF;		    status_changed = 1;		}		goto signal_error;	    }	    if(sr & CANBIT_SR_ERRP) {		m = "ErrorPassive";	    	sr &= ~CANBIT_SR_ERRP;	/* reset error passive bit */	    	if(state != passive) {		    state = passive;		    fflags = MSG_PASSIVE;		    status_changed = 1;	    	}		errorints++;		CANoutl(minor, idr, CANBIT_IR_ERRP);		/* printk("Imask = 0x%08x stat = 0x%08x\n", CANinl(minor, imr), CANinl(minor, sr)); */	    } else if(sr & CANBIT_SR_ERRA) {	    	m = "ErrorActive";	    	sr &= ~CANBIT_SR_ERRA;	/* reset error passive bit */	    	if(state != active) {		    state = active;		    fflags = 0;		    status_changed = 1;		    CANoutl(minor, ier, CANBIT_IR_BOFF	                      + CANBIT_IR_ERRP	                   /* + CANBIT_IR_ERRA */ );	    	}		errorints = 0;	    }	    if (m != NULL && status_changed) {		/* printk(" CAN Status %s Interrupt(%d)\n", m, errorints); */		;	    }	    if(errorints > 40)  { 		/* disable all error interrupts */	    CANoutl(minor, idr, CANBIT_IR_BOFF	                      + CANBIT_IR_ERRP	                      + CANBIT_IR_ERRA);	      }	signal_error:	    /* Insert CAN error in rx queues */	    if(status_changed) {	    /* generate a pseude message with id 0xffffffff */	    /* and put it in every rx queu where someone is waiting */	for(rx_fifo = 0; rx_fifo < CAN_MAX_OPEN; rx_fifo++) {	    /* for every rx fifo */	    if (CanWaitFlag[minor][rx_fifo] == 1) {		/* this FIFO is in use */		RxFifo = &Rx_Buf[minor][rx_fifo]; /* prepare buffer to be used */		(RxFifo->data[RxFifo->head]).flags = fflags; 		(RxFifo->data[RxFifo->head]).id = CANDRIVERERROR;        	(RxFifo->data[RxFifo->head]).length = 0;		RxFifo->status = BUF_OK;		/* handle fifo wrap around */		RxFifo->head = ++(RxFifo->head) % MAX_BUFSIZE;		if(RxFifo->head == RxFifo->tail) {		    printk("CAN[%d][%d] RX: FIFO overrun\n", minor, rx_fifo);		    RxFifo->status = BUF_OVERRUN;		} 		/* tell someone that there is a new error message */		wake_up_interruptible(&CanWait[minor][rx_fifo]); 		status_changed = 0;	    } /* this FIFO is in use */	} /* end for loop filling all rx-fifos */	    } /* Status changed */	} /* end status interrupt */	break;	/* TODO: looping through all interruts */    } /* while interrupt available */#if CONFIG_TIME_MEASURE    reset_led();#endif    return IRQ_RETVAL(IRQ_HANDLED);}/* dump all global CAN registers to printk */void CAN_register_dump(int minor){/* pointer to the global registers of the CAN memory map */volatile at9263can_t *at_can = (at9263can_t *)(can_base[minor]);unsigned long s;    printk("ATMEL AT91SAM9263 CAN register layout\n");#define  printregister(name) printk(" " #name  " \t%p %0x\n", &name , name)    printregister(CAN_Mode);    printregister(CAN_InterruptEnableRegister);    printregister(CAN_InterruptDisableRegister);    printregister(CAN_InterruptMaskRegister);    printregister(CAN_StatusRegister);    s = CAN_StatusRegister;    printk("  %s ",   (s & CANBIT_SR_ERRA) ? "ERROR-Actve" : "");    printk("%s ",     (s & CANBIT_SR_ERRP) ? "ERROR-Passive" : "");    printk("%s ",     (s & CANBIT_SR_BOFF) ? "Bus-Off" : "");    printk("%s\n",     (s & CANBIT_SR_WARN) ? "Warning-Limit" : "");    printregister(CAN_BaudrateRegister);    printregister(CAN_TimerRegister);    printregister(CAN_TimeStampRegister);    printregister(CAN_ErrorCounterRegister);    printregister(CAN_TransferCommandRegister);    printregister(CAN_AbortCommandRegister);    printk("\n");}/* dump the content of the selected message object (MB) to printk * * only 2byte word or short int access is allowed, * each register starts on a 4 byte boundary * Mailbox 0 starts at 0xFFC02C00 * Each Mailbox is built from 8 word registers * * Additional information is unfortunately located on other memory * locations like the acceptance masks*/void CAN_object_dump(int minor, int object){unsigned long v;	/* content value of an register */char *m;/* pointer to an CAN object, "Mailbox" according to the ATMEL doc */volatile unsigned long *cp =		(unsigned long *)(can_base[minor] + 0x200 + (0x20 * object));    printk(KERN_INFO "CAN object %d (at %p)\n", object, cp);    for(v = 0; v < 8; v++) {	printk("%8lx ", *(cp + (v * 4)));	if (v == 3) printk("| ");    }    printk("\n");    v = CAN_OBJ[object].mmr;    v &= CANBIT_MMR_MOT_MSK;    switch(v) {    case CANBIT_MMR_MOT_DISABLE:    	m = "mailbox disabled";    	break;    case CANBIT_MMR_MOT_RX:    	m = "reception mailbox";    	break;    case CANBIT_MMR_MOT_RX_OVL:    	m = "reception mailbox with overwrite";    	break;    case CANBIT_MMR_MOT_TX:    	m = "transmit mailbox";    	break;    case CANBIT_MMR_MOT_RX_RTR:    	m = "consumer mailbox";    	break;    case CANBIT_MMR_MOT_TX_RTR:    	m = "producer mailbox";    	break;    default:	m = "reserveed bit combination in MOT";    }    printk(KERN_INFO  "mailbox type: %s,", m);    v = CAN_OBJ[object].msr;    printk(" DLC=0x%lx", (v & CANBIT_MSR_MDLC_MSK) >> 16);     v = CAN_OBJ[object].msr;    printk(" RTR=0x%lx", (v & CANBIT_MSR_MRTR) >> 20);     printk(" RDY=0x%lx\n", (v & CANBIT_MSR_MRDY) >> 23); }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -