Addresse der Revisionsnummer im SII korrigiert.
/**************************************************************************************************
*
* msr_io.c
*
* Verwaltung der IO-Karten
*
*
* Autor: Wilhelm Hagemeister
*
* (C) Copyright IgH 2002
* Ingenieurgemeinschaft IgH
* Heinz-Bäcker Str. 34
* D-45356 Essen
* Tel.: +49 201/61 99 31
* Fax.: +49 201/61 98 36
* E-mail: sp@igh-essen.com
*
*
* $RCSfile: msr_io.c,v $
* $Revision: 1.9 $
* $Author: ha $
* $Date: 2005/06/24 20:06:56 $
* $State: Exp $
*
*
* $Log: msr_io.c,v $
* Revision 1.9 2005/06/24 20:06:56 ha
* *** empty log message ***
*
* Revision 1.8 2005/06/24 17:39:05 ha
* *** empty log message ***
*
*
*
*
*
*
**************************************************************************************************/
/*--includes-------------------------------------------------------------------------------------*/
#ifndef __KERNEL__
# define __KERNEL__
#endif
#ifndef MODULE
# define MODULE
#endif
#include <linux/delay.h> /* mdelay() */
#include <linux/spinlock.h>
#include <linux/param.h> /* HZ */
#include <linux/sched.h> /* jiffies */
#include <linux/fs.h> /* everything... */
#include <rtai_fifos.h>
#include "msr_io.h"
#include <msr_messages.h>
#include "aim_globals.h"
spinlock_t data_lock = SPIN_LOCK_UNLOCKED;
#include "cif-rtai-io.h"
/*--defines--------------------------------------------------------------------------------------*/
/*--external functions---------------------------------------------------------------------------*/
/*--external data--------------------------------------------------------------------------------*/
/*--public data----------------------------------------------------------------------------------*/
#define PB_CARDS 4
struct {
unsigned int fd;
unsigned int timestamp;
unsigned int fault;
unsigned int active;
void *in_buf;
void *out_buf;
size_t in_buf_len;
size_t out_buf_len;
unsigned int reset_timeout;
} card[PB_CARDS];
/*
***************************************************************************************************
*
* Function: msr_io_init
*
* Beschreibung: Initialisieren der I/O-Karten
*
* Parameter:
*
* Rückgabe:
*
* Status: exp
*
***************************************************************************************************
*/
void x_PB_io(unsigned long card_no) {
int rv = 0;
unsigned int flags;
spin_lock_irqsave(&data_lock, flags);
switch (card_no) {
case 0:
rv = cif_exchange_io(card[0].fd,card[0].in_buf,card[0].out_buf);
if (!rv)
card[0].timestamp = jiffies;
break;
case 1:
rv = cif_exchange_io(card[1].fd,card[1].in_buf,card[1].out_buf);
// rv = cif_read_io(card[1].fd,card[1].in_buf);
// IMO.to_dSPACE.P101.HX_Stat = 51;
// IMO.from_dSPACE.P101.HX_Control |= IMO.to_dSPACE.P101.HX_Stat<<4;
// rv += cif_write_io(card[1].fd,card[1].out_buf);
if (!rv)
card[1].timestamp = jiffies;
break;
/*
case 2:
rv = cif_exchange_io(card[2].fd,&cif_in.P201,&cif_out.P201);
break;
*/
case 3:
rv = cif_exchange_io(card[3].fd,card[3].in_buf,card[3].out_buf);
if (!rv)
card[3].timestamp = jiffies;
break;
}
if (rv) {
msr_print_error("Error during exchange_io %i %i",
card_no, rv );
}
spin_unlock_irqrestore(&data_lock, flags);
}
int msr_io_init()
{
int rv;
memset(card, 0, sizeof(card));
#define FIFO_BUF 10000
if ((rv = rtf_create(0, FIFO_BUF)) < 0) {
msr_print_error("Could not open FIFO %i", rv);
return -1;
}
#ifndef _SIMULATION
/*
card[0].in_buf_len = sizeof(IMO.from_dSPACE);
card[0].out_buf_len = sizeof(IMO.to_dSPACE);
card[0].in_buf = &IMO.from_dSPACE;
card[0].out_buf = &IMO.to_dSPACE;
card[0].active = 1;
if (!(card[0].fd = cif_open_card(0, card[0].in_buf_len,
card[0].out_buf_len, x_PB_io, 0))) {
msr_print_error("Cannot open CIF card PB01");
return -1;
}
card[1].in_buf_len = sizeof(IMO.to_dSPACE.P101);
card[1].out_buf_len = sizeof(IMO.from_dSPACE.P101);
card[1].in_buf = &IMO.to_dSPACE.P101;
card[1].out_buf = &IMO.from_dSPACE.P101;
card[1].active = 1;
if (!(card[1].fd = cif_open_card(1, card[1].in_buf_len,
card[1].out_buf_len, x_PB_io, 1))) {
msr_print_error("Cannot open CIF card P101");
return -1;
}
card[2].in_buf_len = sizeof(IMO.to_dSPACE.P201);
card[2].out_buf_len = sizeof(IMO.from_dSPACE.P201);
card[2].in_buf = &IMO.to_dSPACE.P201;
card[2].out_buf = &IMO.from_dSPACE.P201;
if (!(card[2].fd = cif_open_card(2, card[2].in_buf_len,
card[2].out_buf_len, x_PB_io, 2))) {
msr_print_error("Cannot open CIF card P201");
return -1;
}
*/
card[3].in_buf_len = sizeof(dSPACE.in);
card[3].out_buf_len = sizeof(dSPACE.out);
card[3].in_buf = &dSPACE.in;
card[3].out_buf = &dSPACE.out;
card[3].active = 1;
if (!(card[3].fd = cif_open_card(0, card[3].in_buf_len,
card[3].out_buf_len, x_PB_io,3))) {
msr_print_error("Cannot open CIF card P301");
return -1;
}
//msr_reg_chk_failure(&int_cif_io_fail,TINT,T_CHK_HIGH,0,T_CRIT,"CIF Card was not ready to exchange data");
#endif
return 0;
}
/*
***************************************************************************************************
*
* Function: msr_io_register
*
* Beschreibung: Rohdaten als Kanaele registrieren
*
* Parameter:
*
* Rückgabe:
*
* Status: exp
*
***************************************************************************************************
*/
int msr_io_register()
{
#ifndef _SIMULATION
#endif
return 0;
}
/*
***************************************************************************************************
*
* Function: msr_io_write
*
* Beschreibung: Schreiben der Werte
*
* Parameter:
*
* Rückgabe:
*
* Status: exp
*
***************************************************************************************************
*/
int msr_io_write()
{
static int return_value = 0;
int rv;
int i = 0;
unsigned int flags;
unsigned int com_check_timestamp = 0;
static int COM_Up = 1;
if (jiffies - com_check_timestamp > HZ/20) {
if ( rtf_put_if(0,&IMO,sizeof(IMO)) != sizeof(IMO)) {
//msr_print_error("Could not output data");
}
com_check_timestamp = jiffies;
spin_lock_irqsave(&data_lock, flags);
for ( i=0; i < PB_CARDS; i++) {
// Ignore inactive and cards that already have a fault
if (!card[i].active || card[i].fault)
continue;
// For active cards, check timestamp value. Mark card
// as faulty if there was no data exchange in the last
// 50ms
if (jiffies - card[i].timestamp > HZ/20) {
COM_Up = 0;
card[i].fault = 1;
card[i].reset_timeout = jiffies;
msr_print_error("Card %i timed out", i);
}
}
spin_unlock_irqrestore(&data_lock, flags);
for ( i = 0; i < PB_CARDS; i++ ) {
if (!card[i].active || (card[i].active && !card[i].fault))
continue;
switch (card[i].fault) {
case 1:
rv = cif_write_io(card[i].fd,card[i].out_buf);
if (!rv) {
msr_print_error("Card %i online", i);
card[i].fault = 0;
card[i].timestamp = jiffies;
break;
}
msr_print_error("rv of cif_write_io(%i) = %i",
i, rv);
card[i].fault = 2;
cif_set_host_state(card[i].fd,0);
card[i].reset_timeout = jiffies;
case 2:
if (cif_card_ready(card[i].fd)) {
cif_set_host_state(card[i].fd,1);
card[i].fault = 0;
break;
}
if (jiffies < card[i].reset_timeout)
break;
rv = cif_reset_card(card[i].fd,10,1);
msr_print_error("rv of cif_reset_card(%i) = %i",
i, rv);
// Reset again in 10 seconds
card[i].reset_timeout += 10*HZ;
}
}
}
if (COM_Up)
IMO.to_dSPACE.Status = IMO.from_dSPACE.WatchDog;
// if (return_value)
// int_cif_io_fail = 1;
return return_value;
}
/*
***************************************************************************************************
*
* Function: msr_io_read
*
* Beschreibung: Lesen der Werte
*
* Parameter:
*
* Rückgabe:
*
* Status: exp
*
***************************************************************************************************
*/
int msr_io_read()
{
int return_value = 0;
#ifndef _SIMULATION
int_cif_io_fail = 0;
/*
return_value = cif_exchange_io(fd_PB01,
&cif_out,&cif_in,
sizeof(cif_out),sizeof(cif_in)
);
*/
/* if (return_value) */
/* int_cif_io_fail = 1; */
// printk("%i\n", return_value);
#endif
return return_value;
}
/*
***************************************************************************************************
*
* Function: msr_io_cleanup
*
* Beschreibung: Aufräumen
*
* Parameter:
*
* Rückgabe:
*
* Status: exp
*
***************************************************************************************************
*/
void msr_io_cleanup()
{
/*
cif_set_host_state(card[0].fd,0);
cif_close_card(card[0].fd);
cif_set_host_state(card[1].fd,0);
cif_close_card(card[1].fd);
cif_set_host_state(card[2].fd,0);
cif_close_card(card[2].fd);
*/
cif_set_host_state(card[3].fd,0);
cif_close_card(card[3].fd);
rtf_destroy(0);
}