/* is not very useful! use it if you are sure the tx queu is empty */
int can_Send(struct inode *inode, canmsg_t *Tx)
{
unsigned int minor = MINOR(inode->i_rdev);	
canmsg_t tx;

    if( verify_area(VERIFY_READ,Tx,sizeof(canmsg_t)) ) {
	    return -EINVAL;
    }
    __lddk_copy_from_user((canmsg_t *) &tx, (canmsg_t *) Tx,sizeof(canmsg_t));
    return CAN_SendMessage(minor, &tx);
}
Пример #2
0
/* is not very useful! use it if you are sure the tx queue is empty */
int can_Send(struct inode *inode, canmsg_t *Tx)
{
unsigned int minor = iminor(inode);	
canmsg_t tx;
unsigned long _cnt;

    if( !access_ok(VERIFY_READ, Tx, sizeof(canmsg_t)) ) {
	    return -EINVAL;
    }
    __lddk_copy_from_user((canmsg_t *)&tx, (canmsg_t *)Tx, sizeof(canmsg_t));
    return CAN_SendMessage(minor, &tx);
}
Пример #3
0
void CAN_Com_LoopBack_IRQ(void)
{
  /* initialize the interrupt controller */
  VIC_Config(CAN_ITLine, VIC_IRQ, Priority_1);

  /* initialize the CAN at a standard bitrate, interrupts enabled */
  CAN_InitStructure.CAN_ConfigParameters=CAN_CR_IE;
  CAN_InitStructure.CAN_Bitrate=CAN_BITRATE_100K;
  CAN_Init(&CAN_InitStructure);

  /* switch into Loopback+Silent mode (self-test) */
  CAN_EnterTestMode(CAN_TESTR_LBACK | CAN_TESTR_SILENT);

  /* configure the message objects */
  CAN_InvalidateAllMsgObj();
  CAN_SetTxMsgObj(CAN_TX_MSGOBJ, CAN_EXT_ID);
  CAN_SetRxMsgObj(CAN_RX_MSGOBJ, CAN_EXT_ID, 0, CAN_LAST_EXT_ID, TRUE);

  /* enable global interrupt */
  VIC_ITCmd(CAN_ITLine, ENABLE);

  /* Send the pre-defined frame */
  CAN_SendMessage(CAN_TX_MSGOBJ, &TxCanMsg[2]);

  /* wait until end of transmission */
  CAN_WaitEndOfTx();

  /* reception and release are done in the interrupt handler */

  /* delay to add when the reception occurs */
  delay(0x7FF);

  /* Test Received Msg */
  if((RxCanMsg.IdType == CAN_EXT_ID)&&(RxCanMsg.Id == 0x12345678)&&(RxCanMsg.Dlc == 8)
    &&(RxCanMsg.Data[0]==0x10)&&(RxCanMsg.Data[1]==0x11)&&(RxCanMsg.Data[2]==0x12)&&(RxCanMsg.Data[3]==0x13)
    &&(RxCanMsg.Data[4]==0x14)&&(RxCanMsg.Data[5]==0x15)&&(RxCanMsg.Data[6]==0x16)&&(RxCanMsg.Data[7]==0x17)){
    /*Received Msg OK*/
    LED_ON(LD3);
  } else {
    /*Received Msg KO*/
    LED_ON(LD4);
  }


  /* switch back into Normal mode */
  CAN_LeaveTestMode();

  /* disable interrupts globally */
  VIC_ITCmd(CAN_ITLine, DISABLE);
}
Пример #4
0
void CAN_Com_LoopBack(void)
{
  /* initialize the CAN at a standard bitrate, interrupts disabled */
  CAN_InitStructure.CAN_ConfigParameters=0x0;
  CAN_InitStructure.CAN_Bitrate=CAN_BITRATE_1M;
  CAN_Init(&CAN_InitStructure);

  /* switch into Loopback+Silent mode (self-test) */
  CAN_EnterTestMode(CAN_TESTR_LBACK | CAN_TESTR_SILENT);

  /* configure the message objects */
  CAN_InvalidateAllMsgObj();
  CAN_SetTxMsgObj(CAN_TX_MSGOBJ, CAN_STD_ID);
  CAN_SetRxMsgObj(CAN_RX_MSGOBJ, CAN_STD_ID, 0, CAN_LAST_STD_ID, TRUE);

  /* Send the pre-defined answer */
  CAN_SendMessage(CAN_TX_MSGOBJ, &TxCanMsg[1]);

  /* wait until end of transmission */
  CAN_WaitEndOfTx();

  /* wait for reception of a data frame */
  while (!CAN_ReceiveMessage(CAN_RX_MSGOBJ, FALSE, &RxCanMsg))
  {
    /*Add Timer*/
  }


  /* Test Received Msg */
  if((RxCanMsg.IdType == CAN_STD_ID)&&(RxCanMsg.Id == 0x321)&&(RxCanMsg.Dlc == 4)
    &&(RxCanMsg.Data[0]==0xAA)&&(RxCanMsg.Data[1]==0x55)&&(RxCanMsg.Data[2]==0xAA)&&(RxCanMsg.Data[3]==0x55)){
    /*Received Msg OK*/
    LED_ON(LD2);
  } else {
    /*Received Msg KO*/
    LED_ON(LD4);
  }


  /* release the message objects */
  CAN_ReleaseTxMessage(CAN_TX_MSGOBJ);
  CAN_ReleaseRxMessage(CAN_RX_MSGOBJ);

  /* switch back into Normal mode */
  CAN_LeaveTestMode();

}
Пример #5
0
__LDDK_WRITE_TYPE can_write( __LDDK_WRITE_PARAM )
{
unsigned int minor = __LDDK_MINOR;
msg_fifo_t *TxFifo = &Tx_Buf[minor];
canmsg_t *addr;
canmsg_t tx;
unsigned long flags;
int written        = 0;

    DBGin("can_write");
#ifdef DEBUG_COUNTER
    Cnt1[minor] = Cnt1[minor] + 1;
#endif /* DEBUG_COUNTER */

/* DEBUG_TTY(1, "write: %d", count); */
    DBGprint(DBG_DATA,(" -- write %d msg\n", count));
    /* printk("w[%d/%d]", minor, TxFifo->active); */
    addr = (canmsg_t *)buffer;

    if(verify_area(VERIFY_READ, (canmsg_t *)addr, count * sizeof(canmsg_t))) { 
      DBGout();return -EINVAL;
    }
    while( written < count ) {
	/* enter critical section */
	save_flags(flags);cli();
	/* there are data to write to the network */
	if(TxFifo->free[TxFifo->head] == BUF_FULL) {
/* DEBUG_TTY(1, "ret buffer full"); */
	    /* there is already one message at this place */;
	    DBGout();
	    /* return -ENOSPC; */
            return written;
	}
	if( TxFifo->active ) {
	    /* more than one data and actual data in queue */
	    __lddk_copy_from_user(	/* copy one message to FIFO */
		    (canmsg_t *) &(TxFifo->data[TxFifo->head]), 
		    (canmsg_t *) &addr[written],
		    sizeof(canmsg_t) );
/* DEBUG_TTY(1, " fifo active: id %d/%x; head %d/tail %d", */
/* TxFifo->data[TxFifo->head].id, */
/* TxFifo->data[TxFifo->head].id, */
/* TxFifo->head, */
/* TxFifo->tail); */
	    TxFifo->free[TxFifo->head] = BUF_FULL; /* now this entry is FULL */
	    TxFifo->head = ++(TxFifo->head) % MAX_BUFSIZE;
        } else {
	    __lddk_copy_from_user(
		    (canmsg_t *) &tx, 
		    (canmsg_t *) &addr[written],
		    sizeof(canmsg_t) );
/* DEBUG_TTY(1, " fifo in-active: id %d/%x; head %d/tail %d", */
		/* tx.id, tx.id, */
/* TxFifo->head, */
/* TxFifo->tail ); */
	  /* f - fast -- use interrupts */


            //  Hack hobe TxFifo->active = 0; wird normalerweise auf 1 gesetzt --> und wenn der Inaterrupt
            //  kommt dann wird in Can_Interrupt TxFifo->active wieder zurückgesetzt!!!

            if( count >= 1 ) {
	    /* !!! CHIP abh. !!! */
	    TxFifo->active = 1;
	  }
	  CAN_SendMessage( minor, &tx);  /* Send, no wait */
	}
        written++;
	/* leave critical section */
	restore_flags(flags);
    }
    /* printk("W[%d/%d]", minor, TxFifo->active); */
    DBGout();
    return written;
}
Пример #6
0
__LDDK_WRITE_TYPE can_write( __LDDK_WRITE_PARAM )
{
unsigned int minor = __LDDK_MINOR;
msg_fifo_t *TxFifo = &Tx_Buf[minor];
canmsg_t *addr;
canmsg_t tx;
unsigned long flags = 0;  /* still needed for local_irq_save() ? */
int written         = 0;
int blocking;
unsigned long _cnt;


    DBGin();
    /* spin_lock_irqsave(&write_splock[minor], flags ); */
#ifdef DEBUG_COUNTER
    Cnt1[minor] = Cnt1[minor] + 1;
#endif /* DEBUG_COUNTER */


    /* detect write mode */
    blocking = !(file->f_flags & O_NONBLOCK);

    DBGprint(DBG_DATA,(" -- write %d msg, blocking=%d", (int)count, blocking));
    /* printk("w[%d/%d]", minor, TxFifo->active); */
    addr = (canmsg_t *)buffer;

    if(!access_ok(VERIFY_READ, (canmsg_t *)addr, count * sizeof(canmsg_t))) {
	written = -EINVAL;
	goto can_write_exit;
    }

    /* enter critical section */
    local_irq_save(flags);

    while( written < count ) {

	if(virtual != 0) {
	/* virtual CAN write, put the frame in all RX queues only */
	int rx_fifo;
	msg_fifo_t   *RxFifo; 
	int16_t myindex = 
		(int16_t)((struct _instance_data *)(file->private_data))->rx_index;
	struct timeval  timestamp;

	DBGprint(DBG_DATA,(" -- write msg %d, virtual, blocking=%d, size=%d",
		    (int)written, blocking, (int)sizeof(canmsg_t)));

	/* depending on the number of open processes
	 * the TX data has to be copied in different
	 * RX FIFOs
	 */

	    /* get one message from the userspace buffer */
	    /* FIXME: with CANFD, does it make sense to copy only the number
	     * of data bytes specified in the length field of canmsg_t ?
	     * Instead of  sizeof(canmsg_t) it is something like
	     * sizeof(canmsg_t) - CAN_MSG_LENGTH  + length 
	     */
	    __lddk_copy_from_user(
		    (canmsg_t *) &tx, 
		    (canmsg_t *) &addr[written],
		    sizeof(canmsg_t) );

	    /* we are taking this as receive time stamp */

	    if (use_timestamp[minor]) {
		do_gettimeofday(&timestamp);
	    } else {
		timestamp.tv_sec  = 0;
		timestamp.tv_usec = 0;
	    }

	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 */
		/* printk(KERN_INFO "self copy to [%d][%d]\n", minor, rx_fifo); */
		    
		/*
		 * Don't copy the message in the receive queue
		 * of the process that sent the message unless
		 * this process requested selfreception.
		 */
		if ((myindex == rx_fifo) && 
		    (selfreception[minor][rx_fifo] == 0))
		{
		    /* printk("CAN[%d][%d] Don't copy message in my queue\n",
		     * minor, rx_fifo); */
		    continue;
		}
		// printk(
		// "CAN[%d][%d] Copy message to queue %d\n",
		 //        minor, myindex, rx_fifo);

		/* prepare buffer to be used */
		RxFifo = &Rx_Buf[minor][rx_fifo];

		RxFifo->data[RxFifo->head].flags = 0;
		memcpy(  
		    (void *)&RxFifo->data[RxFifo->head],
		    (void *)&tx,
		    sizeof(canmsg_t));
		/* Now copy the time stamp to the RX FIFO */
		RxFifo->data[RxFifo->head].timestamp.tv_sec = timestamp.tv_sec;
		RxFifo->data[RxFifo->head].timestamp.tv_usec = timestamp.tv_usec;

		/* Set software overflow flag */
		if((RxFifo->status & BUF_OVERRUN) != 0) {
		    RxFifo->data[RxFifo->head].flags |= MSG_BOVR;
		}

		/* Mark message as 'self sent/received' */
		if ((myindex == rx_fifo) && 
		    (selfreception[minor][rx_fifo] != 0))
		{
		    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 */

	}



	} else {
	    /* we have a real hardware to handle */

	/* Do we really need to protect something here ????
	 * e.g. in this case the TxFifo->free[TxFifo->head] value
	 *
	 * If YES, we have to use spinlocks for synchronization
	 */

/* - new Blocking code -- */

	if(blocking) {
	    if(wait_event_interruptible(CanOutWait[minor], \
		    TxFifo->free[TxFifo->head] != BUF_FULL)) {
		written = -ERESTARTSYS;
		goto can_write_exit;
	    }
	} else {
	    /* there are data to write to the network */
	    if(TxFifo->free[TxFifo->head] == BUF_FULL) {
		/* but there is already one message at this place */;
		/* write buffer full in non-blocking mode, leave write() */
		goto can_write_exit;
	    }
	}

/* ---- */

	/*
	 * To know which process sent the message we need an index.
	 * This is used in the TX IRQ to decide in which receive queue
	 * this message has to be copied (selfreception)
	 */
	addr[written].cob = 
		(int16_t)((struct _instance_data *)(file->private_data))->rx_index;
	if( TxFifo->active ) {
	    /* more than one data and actual data in queue,
	     * add this message to the Tx queue 
	     */
	    __lddk_copy_from_user(	/* copy one message to FIFO */
		    (canmsg_t *) &(TxFifo->data[TxFifo->head]), 
		    (canmsg_t *) &addr[written],
		    sizeof(canmsg_t) );
	    TxFifo->free[TxFifo->head] = BUF_FULL; /* now this entry is FULL */
	    /* TxFifo->head = ++(TxFifo->head) % MAX_BUFSIZE; */
	    ++TxFifo->head;
	    (TxFifo->head) %= MAX_BUFSIZE;

	} else {
	    /* copy message into local canmsg_t structure */
	    __lddk_copy_from_user(
		    (canmsg_t *) &tx, 
		    (canmsg_t *) &addr[written],
		    sizeof(canmsg_t) );
	    /* f - fast -- use interrupts */
	    if( count >= 1 ) {
	        /* !!! CHIP abh. !!! */
	        TxFifo->active = 1;
	    }
	    /* write CAN msg data to the chip and enable the tx interrupt */
	    CAN_SendMessage( minor, &tx);  /* Send, no wait */
	}	/* TxFifo->active */
    }
        written++;
    }