Domains, Warten beim Senden, 10kHz.
This commit is contained in:
parent
b691a914b6
commit
3b3b3b1ed1
|
|
@ -18,7 +18,7 @@ obj-m := 8139too-ecat.o ecat-master.o
|
|||
8139too-ecat-objs := 8139too.o
|
||||
|
||||
ecat-master-objs := ec_module.o ec_master.o ec_device.o ec_slave.o \
|
||||
ec_command.o ec_types.o
|
||||
ec_command.o ec_types.o ec_domain.o
|
||||
|
||||
REV = `svnversion $(src)`
|
||||
DATE = `date`
|
||||
|
|
|
|||
|
|
@ -131,6 +131,8 @@ int EtherCAT_device_assign(EtherCAT_device_t *ecd,
|
|||
|
||||
int EtherCAT_device_open(EtherCAT_device_t *ecd)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (!ecd) {
|
||||
printk(KERN_ERR "EtherCAT: Trying to open a NULL device!\n");
|
||||
return -1;
|
||||
|
|
@ -141,6 +143,9 @@ int EtherCAT_device_open(EtherCAT_device_t *ecd)
|
|||
return -1;
|
||||
}
|
||||
|
||||
// Device could have received frames before
|
||||
for (i = 0; i < 4; i++) EtherCAT_device_call_isr(ecd);
|
||||
|
||||
// Reset old device state
|
||||
ecd->state = ECAT_DS_READY;
|
||||
ecd->tx_intr_cnt = 0;
|
||||
|
|
@ -265,7 +270,7 @@ int EtherCAT_device_receive(EtherCAT_device_t *ecd,
|
|||
if (unlikely(ecd->rx_data_length > ECAT_FRAME_BUFFER_SIZE)) {
|
||||
if (likely(ecd->error_reported)) {
|
||||
printk(KERN_ERR "EtherCAT: receive - "
|
||||
" Reveived frame too long (%i Bytes)!\n",
|
||||
" Reveived frame is too long (%i Bytes)!\n",
|
||||
ecd->rx_data_length);
|
||||
ecd->error_reported = 1;
|
||||
}
|
||||
|
|
@ -284,7 +289,7 @@ int EtherCAT_device_receive(EtherCAT_device_t *ecd,
|
|||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
Ruft manuell die Interrupt-Routine der Netzwerkkarte auf.
|
||||
Ruft die Interrupt-Routine der Netzwerkkarte auf.
|
||||
|
||||
@param ecd EtherCAT-Gerät
|
||||
|
||||
|
|
@ -350,3 +355,9 @@ EXPORT_SYMBOL(EtherCAT_device_open);
|
|||
EXPORT_SYMBOL(EtherCAT_device_close);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/* Emacs-Konfiguration
|
||||
;;; Local Variables: ***
|
||||
;;; c-basic-offset:2 ***
|
||||
;;; End: ***
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -0,0 +1,56 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* e c _ d o m a i n . c
|
||||
*
|
||||
* Methoden für Gruppen von EtherCAT-Slaves.
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include <linux/module.h>
|
||||
|
||||
#include "ec_globals.h"
|
||||
#include "ec_domain.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
Konstruktor einer EtherCAT-Domäne.
|
||||
|
||||
@param pd Zeiger auf die zu initialisierende Domäne
|
||||
*/
|
||||
|
||||
void EtherCAT_domain_init(EtherCAT_domain_t *dom)
|
||||
{
|
||||
dom->number = 0;
|
||||
dom->data = NULL;
|
||||
dom->data_size = 0;
|
||||
dom->logical_offset = 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
Destruktor eines Prozessdatenobjekts.
|
||||
|
||||
@param dom Zeiger auf die zu löschenden Prozessdaten
|
||||
*/
|
||||
|
||||
void EtherCAT_domain_clear(EtherCAT_domain_t *dom)
|
||||
{
|
||||
if (dom->data) {
|
||||
kfree(dom->data);
|
||||
dom->data = NULL;
|
||||
}
|
||||
|
||||
dom->data_size = 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/* Emacs-Konfiguration
|
||||
;;; Local Variables: ***
|
||||
;;; c-basic-offset:2 ***
|
||||
;;; End: ***
|
||||
*/
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* e c _ d o m a i n . h
|
||||
*
|
||||
* Struktur für eine Gruppe von EtherCAT-Slaves.
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef _EC_DOMAIN_H_
|
||||
#define _EC_DOMAIN_H_
|
||||
|
||||
#include "ec_globals.h"
|
||||
#include "ec_slave.h"
|
||||
#include "ec_command.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
EtherCAT-Domäne
|
||||
|
||||
Verwaltet die Prozessdaten und das hierfür nötige Kommando einer bestimmten
|
||||
Menge von Slaves.
|
||||
*/
|
||||
|
||||
typedef struct EtherCAT_domain
|
||||
{
|
||||
unsigned int number; /*<< Domänen-Identifikation */
|
||||
EtherCAT_command_t command; /**< Kommando zum Senden und Empfangen der
|
||||
Prozessdaten */
|
||||
unsigned char *data; /**< Zeiger auf Speicher mit Prozessdaten */
|
||||
unsigned int data_size; /**< Größe des Prozessdatenspeichers */
|
||||
unsigned int logical_offset; /**< Logische Basisaddresse */
|
||||
}
|
||||
EtherCAT_domain_t;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void EtherCAT_domain_init(EtherCAT_domain_t *);
|
||||
void EtherCAT_domain_clear(EtherCAT_domain_t *);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#endif
|
||||
|
||||
/* Emacs-Konfiguration
|
||||
;;; Local Variables: ***
|
||||
;;; c-basic-offset:2 ***
|
||||
;;; End: ***
|
||||
*/
|
||||
|
|
@ -18,6 +18,11 @@
|
|||
*/
|
||||
#define ECAT_FRAME_BUFFER_SIZE 1500
|
||||
|
||||
/**
|
||||
Maximale Anzahl der Prozessdatendomänen in einem Master
|
||||
*/
|
||||
#define ECAT_MAX_DOMAINS 10
|
||||
|
||||
/**
|
||||
NULL-Define, falls noch nicht definiert.
|
||||
*/
|
||||
|
|
@ -69,4 +74,8 @@ EtherCAT_state_t;
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct EtherCAT_master EtherCAT_master_t;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -22,22 +22,20 @@
|
|||
/**
|
||||
Konstruktor des EtherCAT-Masters.
|
||||
|
||||
@param master Zeiger auf den zu initialisierenden
|
||||
EtherCAT-Master
|
||||
|
||||
@return 0 bei Erfolg, sonst < 0 (= dev ist NULL)
|
||||
@param master Zeiger auf den zu initialisierenden EtherCAT-Master
|
||||
*/
|
||||
|
||||
void EtherCAT_master_init(EtherCAT_master_t *master)
|
||||
{
|
||||
master->slaves = NULL;
|
||||
master->slave_count = 0;
|
||||
master->dev = NULL;
|
||||
master->command_index = 0x00;
|
||||
master->tx_data_length = 0;
|
||||
master->process_data = NULL;
|
||||
master->process_data_length = 0;
|
||||
master->rx_data_length = 0;
|
||||
master->domain_count = 0;
|
||||
master->debug_level = 0;
|
||||
master->tx_time = 0;
|
||||
master->rx_time = 0;
|
||||
master->rx_tries = 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -53,15 +51,14 @@ void EtherCAT_master_init(EtherCAT_master_t *master)
|
|||
|
||||
void EtherCAT_master_clear(EtherCAT_master_t *master)
|
||||
{
|
||||
// Remove all slaves
|
||||
EtherCAT_clear_slaves(master);
|
||||
unsigned int i;
|
||||
|
||||
if (master->process_data) {
|
||||
kfree(master->process_data);
|
||||
master->process_data = NULL;
|
||||
// Remove domains
|
||||
for (i = 0; i < master->domain_count; i++) {
|
||||
EtherCAT_domain_clear(master->domains + i);
|
||||
}
|
||||
|
||||
master->process_data_length = 0;
|
||||
master->domain_count = 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -82,14 +79,12 @@ int EtherCAT_master_open(EtherCAT_master_t *master,
|
|||
EtherCAT_device_t *device)
|
||||
{
|
||||
if (!master || !device) {
|
||||
printk(KERN_ERR "EtherCAT: Illegal parameters"
|
||||
" for master_open()!\n");
|
||||
printk(KERN_ERR "EtherCAT: Illegal parameters for master_open()!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (master->dev) {
|
||||
printk(KERN_ERR "EtherCAT: Master already"
|
||||
" has a device.\n");
|
||||
printk(KERN_ERR "EtherCAT: Master already has a device.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -197,8 +192,7 @@ int EtherCAT_simple_send(EtherCAT_master_t *master,
|
|||
framelength = length + 2;
|
||||
|
||||
if (unlikely(framelength > ECAT_FRAME_BUFFER_SIZE)) {
|
||||
printk(KERN_ERR "EtherCAT: Frame too long (%i)!\n",
|
||||
framelength);
|
||||
printk(KERN_ERR "EtherCAT: Frame too long (%i)!\n", framelength);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -256,6 +250,9 @@ int EtherCAT_simple_send(EtherCAT_master_t *master,
|
|||
printk(KERN_DEBUG "device send...\n");
|
||||
}
|
||||
|
||||
// Zeit nehmen
|
||||
rdtscl(master->tx_time);
|
||||
|
||||
// Send frame
|
||||
if (unlikely(EtherCAT_device_send(master->dev,
|
||||
master->tx_data,
|
||||
|
|
@ -297,8 +294,8 @@ int EtherCAT_simple_receive(EtherCAT_master_t *master,
|
|||
master->rx_data_length = (unsigned int) ret;
|
||||
|
||||
if (unlikely(master->rx_data_length < 2)) {
|
||||
printk(KERN_ERR "EtherCAT: Received frame with"
|
||||
" incomplete EtherCAT header!\n");
|
||||
printk(KERN_ERR "EtherCAT: Received frame with incomplete"
|
||||
" EtherCAT header!\n");
|
||||
output_debug_data(master);
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -308,8 +305,8 @@ int EtherCAT_simple_receive(EtherCAT_master_t *master,
|
|||
| (master->rx_data[0] & 0xFF);
|
||||
|
||||
if (unlikely(length > master->rx_data_length)) {
|
||||
printk(KERN_ERR "EtherCAT: Received corrupted"
|
||||
" frame (length does not match)!\n");
|
||||
printk(KERN_ERR "EtherCAT: Received corrupted frame (length does"
|
||||
" not match)!\n");
|
||||
output_debug_data(master);
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -337,8 +334,9 @@ int EtherCAT_simple_receive(EtherCAT_master_t *master,
|
|||
memcpy(cmd->data, master->rx_data + 2 + 10, length);
|
||||
|
||||
// Working-Counter setzen
|
||||
cmd->working_counter = ((master->rx_data[length + 2 + 10] & 0xFF)
|
||||
| ((master->rx_data[length + 2 + 11] & 0xFF) << 8));
|
||||
cmd->working_counter
|
||||
= ((master->rx_data[length + 2 + 10] & 0xFF)
|
||||
| ((master->rx_data[length + 2 + 11] & 0xFF) << 8));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -374,8 +372,17 @@ int EtherCAT_check_slaves(EtherCAT_master_t *master,
|
|||
{
|
||||
EtherCAT_command_t cmd;
|
||||
EtherCAT_slave_t *cur;
|
||||
unsigned int i, j, found, length, pos;
|
||||
unsigned int i, j, found, size, offset;
|
||||
unsigned char data[2];
|
||||
EtherCAT_domain_t *dom;
|
||||
|
||||
// Clear domains
|
||||
for (i = 0; i < master->domain_count; i++) {
|
||||
printk(KERN_DEBUG "EtherCAT: Clearing domain %i!\n",
|
||||
master->domains[i].number);
|
||||
EtherCAT_domain_clear(master->domains + i);
|
||||
}
|
||||
master->domain_count = 0;
|
||||
|
||||
if (unlikely(!slave_count)) {
|
||||
printk(KERN_ERR "EtherCAT: No slaves in list!\n");
|
||||
|
|
@ -394,8 +401,8 @@ int EtherCAT_check_slaves(EtherCAT_master_t *master,
|
|||
cmd.working_counter, slave_count);
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
printk("EtherCAT: Found all %i slaves.\n", slave_count);
|
||||
|
||||
printk("EtherCAT: Found all %i slaves.\n", slave_count);
|
||||
|
||||
// For every slave in the list
|
||||
for (i = 0; i < slave_count; i++)
|
||||
|
|
@ -403,8 +410,7 @@ int EtherCAT_check_slaves(EtherCAT_master_t *master,
|
|||
cur = &slaves[i];
|
||||
|
||||
if (unlikely(!cur->desc)) {
|
||||
printk(KERN_ERR "EtherCAT: Slave %i has"
|
||||
" no description.\n", i);
|
||||
printk(KERN_ERR "EtherCAT: Slave %i has no description.\n", i);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -443,6 +449,7 @@ int EtherCAT_check_slaves(EtherCAT_master_t *master,
|
|||
}
|
||||
|
||||
// Get base data
|
||||
|
||||
cur->type = cmd.data[0];
|
||||
cur->revision = cmd.data[1];
|
||||
cur->build = cmd.data[2] | (cmd.data[3] << 8);
|
||||
|
|
@ -515,62 +522,81 @@ int EtherCAT_check_slaves(EtherCAT_master_t *master,
|
|||
cur->vendor_id, cur->product_code, i);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Check, if process data domain already exists...
|
||||
found = 0;
|
||||
for (j = 0; j < master->domain_count; j++) {
|
||||
if (cur->domain == master->domains[j].number) {
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Create process data domain
|
||||
if (!found) {
|
||||
if (master->domain_count + 1 >= ECAT_MAX_DOMAINS) {
|
||||
printk(KERN_ERR "EtherCAT: Too many domains!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
EtherCAT_domain_init(&master->domains[master->domain_count]);
|
||||
master->domains[master->domain_count].number = cur->domain;
|
||||
master->domain_count++;
|
||||
}
|
||||
}
|
||||
|
||||
length = 0;
|
||||
for (i = 0; i < slave_count; i++)
|
||||
// Calculate domain sizes
|
||||
offset = 0;
|
||||
for (i = 0; i < master->domain_count; i++)
|
||||
{
|
||||
length += slaves[i].desc->data_length;
|
||||
dom = master->domains + i;
|
||||
|
||||
dom->logical_offset = offset;
|
||||
|
||||
// For every slave in the list
|
||||
size = 0;
|
||||
for (j = 0; j < slave_count; j++) {
|
||||
if (slaves[j].domain == dom->number) {
|
||||
size += slaves[j].desc->process_data_size;
|
||||
}
|
||||
}
|
||||
|
||||
if (size > ECAT_FRAME_BUFFER_SIZE - 14) {
|
||||
printk(KERN_ERR "EtherCAT: Oversized domain %i: %i / %i Bytes!\n",
|
||||
dom->number, size, ECAT_FRAME_BUFFER_SIZE - 14);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!(dom->data = (unsigned char *) kmalloc(sizeof(unsigned char)
|
||||
* size, GFP_KERNEL))) {
|
||||
printk(KERN_ERR "EtherCAT: Could not allocate"
|
||||
" %i bytes of domain data.\n", size);
|
||||
return -1;
|
||||
}
|
||||
|
||||
dom->data_size = size;
|
||||
memset(dom->data, 0x00, size);
|
||||
|
||||
printk(KERN_INFO "EtherCAT: Domain %i: %i Bytes of process data.\n",
|
||||
dom->number, size);
|
||||
|
||||
// Set logical addresses and data pointers of domain slaves
|
||||
size = 0;
|
||||
for (j = 0; j < slave_count; j++) {
|
||||
if (slaves[j].domain == dom->number) {
|
||||
slaves[j].process_data = dom->data + size;
|
||||
slaves[j].logical_address = dom->logical_offset + size;
|
||||
size += slaves[j].desc->process_data_size;
|
||||
}
|
||||
}
|
||||
|
||||
offset += size;
|
||||
}
|
||||
|
||||
if (unlikely((master->process_data = (unsigned char *)
|
||||
kmalloc(sizeof(unsigned char)
|
||||
* length, GFP_KERNEL)) == NULL)) {
|
||||
printk(KERN_ERR "EtherCAT: Could not allocate %i"
|
||||
" bytes for process data.\n", length);
|
||||
return -1;
|
||||
}
|
||||
|
||||
master->process_data_length = length;
|
||||
memset(master->process_data, 0x00, length);
|
||||
|
||||
pos = 0;
|
||||
for (i = 0; i < slave_count; i++)
|
||||
{
|
||||
slaves[i].process_data = master->process_data + pos;
|
||||
slaves[i].logical_address0 = pos;
|
||||
|
||||
printk(KERN_DEBUG "EtherCAT: Slave %i -"
|
||||
" Address 0x%X, \"%s %s\", s/n %u\n",
|
||||
i, pos, slaves[i].desc->vendor_name,
|
||||
slaves[i].desc->product_name,
|
||||
slaves[i].serial_number);
|
||||
|
||||
pos += slaves[i].desc->data_length;
|
||||
}
|
||||
|
||||
master->slaves = slaves;
|
||||
master->slave_count = slave_count;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
Entfernt den Zeiger auf das Slave-Array.
|
||||
|
||||
@param master EtherCAT-Master
|
||||
*/
|
||||
|
||||
void EtherCAT_clear_slaves(EtherCAT_master_t *master)
|
||||
{
|
||||
master->slaves = NULL;
|
||||
master->slave_count = 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
Liest Daten aus dem Slave-Information-Interface
|
||||
eines EtherCAT-Slaves.
|
||||
|
|
@ -605,12 +631,12 @@ int EtherCAT_read_slave_information(EtherCAT_master_t *master,
|
|||
EtherCAT_command_write(&cmd, node_address, 0x502, 6, data);
|
||||
|
||||
if (unlikely(EtherCAT_simple_send_receive(master, &cmd) < 0))
|
||||
return -3;
|
||||
return -1;
|
||||
|
||||
if (unlikely(cmd.working_counter != 1)) {
|
||||
printk(KERN_ERR "EtherCAT: SII-read - Slave"
|
||||
" %04X did not respond!\n", node_address);
|
||||
return -4;
|
||||
printk(KERN_ERR "EtherCAT: SII-read - Slave %04X did not respond!\n",
|
||||
node_address);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Der Slave legt die Informationen des Slave-Information-Interface
|
||||
|
|
@ -625,12 +651,12 @@ int EtherCAT_read_slave_information(EtherCAT_master_t *master,
|
|||
EtherCAT_command_read(&cmd, node_address, 0x502, 10);
|
||||
|
||||
if (unlikely(EtherCAT_simple_send_receive(master, &cmd) != 0))
|
||||
return -3;
|
||||
return -1;
|
||||
|
||||
if (unlikely(cmd.working_counter != 1)) {
|
||||
printk(KERN_ERR "EtherCAT: SII-read status -"
|
||||
" Slave %04X did not respond!\n", node_address);
|
||||
return -4;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (likely((cmd.data[1] & 0x81) == 0)) {
|
||||
|
|
@ -642,8 +668,8 @@ int EtherCAT_read_slave_information(EtherCAT_master_t *master,
|
|||
}
|
||||
|
||||
if (unlikely(!tries_left)) {
|
||||
printk(KERN_WARNING "EtherCAT: SSI-read."
|
||||
" Slave %04X timed out!\n", node_address);
|
||||
printk(KERN_WARNING "EtherCAT: SSI-read. Slave %04X timed out!\n",
|
||||
node_address);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -784,7 +810,7 @@ int EtherCAT_activate_slave(EtherCAT_master_t *master,
|
|||
printk(KERN_ERR "EtherCAT: Resetting FMMUs -"
|
||||
" Slave %04X did not respond!\n",
|
||||
slave->station_address);
|
||||
return -2;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Resetting Sync Manager channels
|
||||
|
|
@ -803,7 +829,7 @@ int EtherCAT_activate_slave(EtherCAT_master_t *master,
|
|||
printk(KERN_ERR "EtherCAT: Resetting SMs -"
|
||||
" Slave %04X did not respond!\n",
|
||||
slave->station_address);
|
||||
return -2;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -823,7 +849,7 @@ int EtherCAT_activate_slave(EtherCAT_master_t *master,
|
|||
printk(KERN_ERR "EtherCAT: Setting SM0 -"
|
||||
" Slave %04X did not respond!\n",
|
||||
slave->station_address);
|
||||
return -3;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -839,7 +865,7 @@ int EtherCAT_activate_slave(EtherCAT_master_t *master,
|
|||
printk(KERN_ERR "EtherCAT: Setting SM1 -"
|
||||
" Slave %04X did not respond!\n",
|
||||
slave->station_address);
|
||||
return -2;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -848,18 +874,24 @@ int EtherCAT_activate_slave(EtherCAT_master_t *master,
|
|||
|
||||
if (unlikely(EtherCAT_state_change(master, slave,
|
||||
ECAT_STATE_PREOP) != 0))
|
||||
return -5;
|
||||
return -1;
|
||||
|
||||
// Set FMMU's
|
||||
|
||||
if (desc->fmmu0)
|
||||
{
|
||||
if (unlikely(!slave->process_data)) {
|
||||
printk(KERN_ERR "EtherCAT: Warning - Slave %04X is not assigned to any"
|
||||
" process data object!\n", slave->station_address);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(fmmu, desc->fmmu0, 16);
|
||||
|
||||
fmmu[0] = slave->logical_address0 & 0x000000FF;
|
||||
fmmu[1] = (slave->logical_address0 & 0x0000FF00) >> 8;
|
||||
fmmu[2] = (slave->logical_address0 & 0x00FF0000) >> 16;
|
||||
fmmu[3] = (slave->logical_address0 & 0xFF000000) >> 24;
|
||||
fmmu[0] = slave->logical_address & 0x000000FF;
|
||||
fmmu[1] = (slave->logical_address & 0x0000FF00) >> 8;
|
||||
fmmu[2] = (slave->logical_address & 0x00FF0000) >> 16;
|
||||
fmmu[3] = (slave->logical_address & 0xFF000000) >> 24;
|
||||
|
||||
EtherCAT_command_write(&cmd, slave->station_address,
|
||||
0x0600, 16, fmmu);
|
||||
|
|
@ -871,7 +903,7 @@ int EtherCAT_activate_slave(EtherCAT_master_t *master,
|
|||
printk(KERN_ERR "EtherCAT: Setting FMMU0 -"
|
||||
" Slave %04X did not respond!\n",
|
||||
slave->station_address);
|
||||
return -2;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -891,7 +923,7 @@ int EtherCAT_activate_slave(EtherCAT_master_t *master,
|
|||
printk(KERN_ERR "EtherCAT: Setting SM0 -"
|
||||
" Slave %04X did not respond!\n",
|
||||
slave->station_address);
|
||||
return -3;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -907,7 +939,7 @@ int EtherCAT_activate_slave(EtherCAT_master_t *master,
|
|||
printk(KERN_ERR "EtherCAT: Setting SM1 -"
|
||||
" Slave %04X did not respond!\n",
|
||||
slave->station_address);
|
||||
return -3;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -924,7 +956,7 @@ int EtherCAT_activate_slave(EtherCAT_master_t *master,
|
|||
printk(KERN_ERR "EtherCAT: Setting SM2 -"
|
||||
" Slave %04X did not respond!\n",
|
||||
slave->station_address);
|
||||
return -3;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -940,19 +972,19 @@ int EtherCAT_activate_slave(EtherCAT_master_t *master,
|
|||
printk(KERN_ERR "EtherCAT: Setting SM3 -"
|
||||
" Slave %04X did not respond!\n",
|
||||
slave->station_address);
|
||||
return -3;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// Change state to SAVEOP
|
||||
if (unlikely(EtherCAT_state_change(master, slave,
|
||||
ECAT_STATE_SAVEOP) != 0))
|
||||
return -12;
|
||||
return -1;
|
||||
|
||||
// Change state to OP
|
||||
if (unlikely(EtherCAT_state_change(master, slave,
|
||||
ECAT_STATE_OP) != 0))
|
||||
return -13;
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -981,157 +1013,80 @@ int EtherCAT_deactivate_slave(EtherCAT_master_t *master,
|
|||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
Aktiviert alle Slaves.
|
||||
|
||||
@see EtherCAT_activate_slave
|
||||
Sendet und empfängt Prozessdaten der angegebenen Domäne
|
||||
|
||||
@param master EtherCAT-Master
|
||||
domain Domäne
|
||||
|
||||
@return 0 bei Erfolg, sonst < 0
|
||||
*/
|
||||
|
||||
int EtherCAT_activate_all_slaves(EtherCAT_master_t *master)
|
||||
int EtherCAT_process_data_cycle(EtherCAT_master_t *master,
|
||||
unsigned int domain)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int i, tries;
|
||||
EtherCAT_domain_t *dom = NULL;
|
||||
|
||||
for (i = 0; i < master->slave_count; i++)
|
||||
{
|
||||
if (unlikely(EtherCAT_activate_slave(master,
|
||||
&master->slaves[i]) < 0))
|
||||
return -1;
|
||||
for (i = 0; i < master->domain_count; i++) {
|
||||
if (master->domains[i].number == domain) {
|
||||
dom = master->domains + i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
Deaktiviert alle Slaves.
|
||||
|
||||
@see EtherCAT_deactivate_slave
|
||||
|
||||
@param master EtherCAT-Master
|
||||
|
||||
@return 0 bei Erfolg, sonst < 0
|
||||
*/
|
||||
|
||||
int EtherCAT_deactivate_all_slaves(EtherCAT_master_t *master)
|
||||
{
|
||||
unsigned int i;
|
||||
int ret = 0;
|
||||
|
||||
for (i = 0; i < master->slave_count; i++)
|
||||
{
|
||||
if (unlikely(EtherCAT_deactivate_slave(master,
|
||||
&master->slaves[i]) < 0))
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
Sendet alle Prozessdaten an die Slaves.
|
||||
|
||||
Erstellt ein "logical read write"-Kommando mit den
|
||||
Prozessdaten des Masters und sendet es an den Bus.
|
||||
|
||||
@param master EtherCAT-Master
|
||||
|
||||
@return 0 bei Erfolg, sonst < 0
|
||||
*/
|
||||
|
||||
int EtherCAT_write_process_data(EtherCAT_master_t *master)
|
||||
{
|
||||
EtherCAT_command_logical_read_write(&master->process_data_command,
|
||||
0, master->process_data_length,
|
||||
master->process_data);
|
||||
|
||||
if (unlikely(EtherCAT_simple_send(master,
|
||||
&master->process_data_command) < 0))
|
||||
{
|
||||
printk(KERN_ERR "EtherCAT: Could not send"
|
||||
" process data command!\n");
|
||||
if (unlikely(!dom)) {
|
||||
printk(KERN_ERR "EtherCAT: No such domain: %i!\n", domain);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EtherCAT_command_logical_read_write(&dom->command,
|
||||
dom->logical_offset, dom->data_size,
|
||||
dom->data);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
Empfängt alle Prozessdaten von den Slaves.
|
||||
|
||||
Empfängt ein zuvor gesendetes "logical read write"-Kommando
|
||||
und kopiert die empfangenen daten in den Prozessdatenspeicher
|
||||
des Masters.
|
||||
|
||||
@param master EtherCAT-Master
|
||||
|
||||
@return 0 bei Erfolg, sonst < 0
|
||||
*/
|
||||
|
||||
int EtherCAT_read_process_data(EtherCAT_master_t *master)
|
||||
{
|
||||
unsigned int tries_left;
|
||||
|
||||
EtherCAT_device_call_isr(master->dev);
|
||||
|
||||
tries_left = 20;
|
||||
while (unlikely(master->dev->state == ECAT_DS_SENT
|
||||
&& tries_left))
|
||||
{
|
||||
udelay(1);
|
||||
EtherCAT_device_call_isr(master->dev);
|
||||
tries_left--;
|
||||
if (unlikely(EtherCAT_simple_send(master, &dom->command) < 0)) {
|
||||
printk(KERN_ERR "EtherCAT: Could not send process data command!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (unlikely(!tries_left))
|
||||
{
|
||||
udelay(3);
|
||||
|
||||
#if 1
|
||||
// Warten
|
||||
tries = 0;
|
||||
EtherCAT_device_call_isr(master->dev);
|
||||
while (unlikely(master->dev->state == ECAT_DS_SENT && tries < 100)) {
|
||||
udelay(1);
|
||||
EtherCAT_device_call_isr(master->dev);
|
||||
tries++;
|
||||
}
|
||||
|
||||
rdtscl(master->rx_time);
|
||||
master->rx_tries = tries;
|
||||
|
||||
if (unlikely(tries == 100)) {
|
||||
printk(KERN_ERR "EtherCAT: Timeout while receiving process data!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (unlikely(EtherCAT_simple_receive(master,
|
||||
&master->process_data_command) < 0))
|
||||
{
|
||||
if (unlikely(EtherCAT_simple_receive(master, &dom->command) < 0)) {
|
||||
printk(KERN_ERR "EtherCAT: Could not receive cyclic command!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (unlikely(master->process_data_command.state != ECAT_CS_RECEIVED))
|
||||
{
|
||||
if (unlikely(dom->command.state != ECAT_CS_RECEIVED)) {
|
||||
printk(KERN_WARNING "EtherCAT: Process data command not received!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Daten von Kommando in Prozessdaten des Master kopieren
|
||||
memcpy(master->process_data, master->process_data_command.data,
|
||||
master->process_data_length);
|
||||
// Daten vom Kommando in den Prozessdatenspeicher kopieren
|
||||
memcpy(dom->data, dom->command.data, dom->data_size);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
Verwirft das zuletzt gesendete Prozessdatenkommando.
|
||||
|
||||
@param master EtherCAT-Master
|
||||
*/
|
||||
|
||||
void EtherCAT_clear_process_data(EtherCAT_master_t *master)
|
||||
{
|
||||
EtherCAT_device_call_isr(master->dev);
|
||||
master->dev->state = ECAT_DS_READY;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
Gibt Frame-Inhalte zwecks Debugging aus.
|
||||
|
||||
|
|
@ -1171,11 +1126,15 @@ EXPORT_SYMBOL(EtherCAT_master_init);
|
|||
EXPORT_SYMBOL(EtherCAT_master_clear);
|
||||
EXPORT_SYMBOL(EtherCAT_master_open);
|
||||
EXPORT_SYMBOL(EtherCAT_master_close);
|
||||
EXPORT_SYMBOL(EtherCAT_read_process_data);
|
||||
EXPORT_SYMBOL(EtherCAT_write_process_data);
|
||||
EXPORT_SYMBOL(EtherCAT_check_slaves);
|
||||
EXPORT_SYMBOL(EtherCAT_activate_all_slaves);
|
||||
EXPORT_SYMBOL(EtherCAT_clear_process_data);
|
||||
EXPORT_SYMBOL(EtherCAT_deactivate_all_slaves);
|
||||
EXPORT_SYMBOL(EtherCAT_activate_slave);
|
||||
EXPORT_SYMBOL(EtherCAT_deactivate_slave);
|
||||
EXPORT_SYMBOL(EtherCAT_process_data_cycle);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/* Emacs-Konfiguration
|
||||
;;; Local Variables: ***
|
||||
;;; c-basic-offset:2 ***
|
||||
;;; End: ***
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
#include "ec_device.h"
|
||||
#include "ec_slave.h"
|
||||
#include "ec_command.h"
|
||||
#include "ec_domain.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
@ -24,19 +25,10 @@
|
|||
dem zugewiesenen EtherCAT-Gerät.
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
struct EtherCAT_master
|
||||
{
|
||||
EtherCAT_slave_t *slaves; /**< Zeiger auf statischen Speicher
|
||||
mit Slave-Informationen */
|
||||
unsigned int slave_count; /**< Anzahl der Slaves in slaves */
|
||||
|
||||
EtherCAT_command_t process_data_command; /**< Kommando zum Senden und
|
||||
Empfangen der Prozessdaten */
|
||||
|
||||
EtherCAT_device_t *dev; /**< Zeiger auf das zugewiesene EtherCAT-Gerät */
|
||||
|
||||
unsigned char command_index; /**< Aktueller Kommando-Index */
|
||||
|
||||
unsigned char tx_data[ECAT_FRAME_BUFFER_SIZE]; /**< Statischer Speicher
|
||||
für zu sendende Daten */
|
||||
unsigned int tx_data_length; /**< Länge der Daten im Sendespeicher */
|
||||
|
|
@ -44,13 +36,13 @@ typedef struct
|
|||
eine Kopie des Rx-Buffers
|
||||
im EtherCAT-Gerät */
|
||||
unsigned int rx_data_length; /**< Länge der Daten im Empfangsspeicher */
|
||||
|
||||
unsigned char *process_data; /**< Zeiger auf Speicher mit Prozessdaten */
|
||||
unsigned int process_data_length; /**< Länge der Prozessdaten */
|
||||
|
||||
EtherCAT_domain_t domains[ECAT_MAX_DOMAINS]; /** Prozessdatendomänen */
|
||||
unsigned int domain_count;
|
||||
int debug_level; /**< Debug-Level im Master-Code */
|
||||
}
|
||||
EtherCAT_master_t;
|
||||
unsigned long tx_time; /**< Zeit des letzten Sendens */
|
||||
unsigned long rx_time; /**< Zeit des letzten Empfangs */
|
||||
unsigned int rx_tries; /**< Anzahl Warteschleifen beim letzen Enpfang */
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
@ -68,22 +60,17 @@ int EtherCAT_simple_send(EtherCAT_master_t *, EtherCAT_command_t *);
|
|||
int EtherCAT_simple_receive(EtherCAT_master_t *, EtherCAT_command_t *);
|
||||
|
||||
// Slave management
|
||||
int EtherCAT_check_slaves(EtherCAT_master_t *, EtherCAT_slave_t *, unsigned int);
|
||||
void EtherCAT_clear_slaves(EtherCAT_master_t *);
|
||||
int EtherCAT_read_slave_information(EtherCAT_master_t *,
|
||||
unsigned short int,
|
||||
unsigned short int,
|
||||
unsigned int *);
|
||||
int EtherCAT_check_slaves(EtherCAT_master_t *, EtherCAT_slave_t *,
|
||||
unsigned int);
|
||||
int EtherCAT_read_slave_information(EtherCAT_master_t *, unsigned short int,
|
||||
unsigned short int, unsigned int *);
|
||||
int EtherCAT_activate_slave(EtherCAT_master_t *, EtherCAT_slave_t *);
|
||||
int EtherCAT_deactivate_slave(EtherCAT_master_t *, EtherCAT_slave_t *);
|
||||
int EtherCAT_activate_all_slaves(EtherCAT_master_t *);
|
||||
int EtherCAT_deactivate_all_slaves(EtherCAT_master_t *);
|
||||
int EtherCAT_state_change(EtherCAT_master_t *, EtherCAT_slave_t *, unsigned char);
|
||||
int EtherCAT_state_change(EtherCAT_master_t *, EtherCAT_slave_t *,
|
||||
unsigned char);
|
||||
|
||||
// Process data
|
||||
int EtherCAT_write_process_data(EtherCAT_master_t *);
|
||||
int EtherCAT_read_process_data(EtherCAT_master_t *);
|
||||
void EtherCAT_clear_process_data(EtherCAT_master_t *);
|
||||
int EtherCAT_process_data_cycle(EtherCAT_master_t *, unsigned int);
|
||||
|
||||
// Private functions
|
||||
void output_debug_data(const EtherCAT_master_t *);
|
||||
|
|
@ -91,3 +78,9 @@ void output_debug_data(const EtherCAT_master_t *);
|
|||
/*****************************************************************************/
|
||||
|
||||
#endif
|
||||
|
||||
/* Emacs-Konfiguration
|
||||
;;; Local Variables: ***
|
||||
;;; c-basic-offset:2 ***
|
||||
;;; End: ***
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -239,7 +239,7 @@ EtherCAT_master_t *EtherCAT_request(int index)
|
|||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
Gibt einen zuvor reservierten EtherCAT-Master wieder frei.
|
||||
Gibt einen zuvor angeforderten EtherCAT-Master wieder frei.
|
||||
|
||||
@param master Zeiger auf den freizugebenden EtherCAT-Master.
|
||||
*/
|
||||
|
|
@ -267,7 +267,7 @@ void EtherCAT_release(EtherCAT_master_t *master)
|
|||
}
|
||||
}
|
||||
|
||||
printk(KERN_WARNING "EtherCAT: Master %X was never reserved!\n",
|
||||
printk(KERN_WARNING "EtherCAT: Master %X was never requested!\n",
|
||||
(unsigned int) master);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,9 @@
|
|||
|
||||
Initialisiert einen EtherCAT-Slave.
|
||||
|
||||
ACHTUNG! Dieser Konstruktor wird quasi nie aufgerufen. Bitte immer das
|
||||
Makro ECAT_INIT_SLAVE() in ec_slave.h anpassen!
|
||||
|
||||
@param slave Zeiger auf den zu initialisierenden Slave
|
||||
*/
|
||||
|
||||
|
|
@ -35,9 +38,11 @@ void EtherCAT_slave_init(EtherCAT_slave_t *slave)
|
|||
slave->revision_number = 0;
|
||||
slave->serial_number = 0;
|
||||
slave->desc = NULL;
|
||||
slave->logical_address0 = 0;
|
||||
slave->logical_address = 0;
|
||||
slave->current_state = ECAT_STATE_UNKNOWN;
|
||||
slave->requested_state = ECAT_STATE_UNKNOWN;
|
||||
slave->process_data = NULL;
|
||||
slave->domain = 0;
|
||||
slave->error_reported = 0;
|
||||
}
|
||||
|
||||
|
|
@ -97,7 +102,7 @@ int EtherCAT_read_value(EtherCAT_slave_t *slave,
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (unlikely(channel >= slave->desc->channels)) {
|
||||
if (unlikely(channel >= slave->desc->channel_count)) {
|
||||
if (likely(slave->error_reported)) {
|
||||
printk(KERN_WARNING "EtherCAT: Reading failed on slave %4X (addr %0X)"
|
||||
" - Type (%s %s) has no channel %i.\n",
|
||||
|
|
@ -109,6 +114,16 @@ int EtherCAT_read_value(EtherCAT_slave_t *slave,
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (unlikely(!slave->process_data)) {
|
||||
if (likely(slave->error_reported)) {
|
||||
printk(KERN_WARNING "EtherCAT: Reading failed on slave %4X (addr %0X)"
|
||||
" - Slave does not belong to any process data object!\n",
|
||||
slave->station_address, (unsigned int) slave);
|
||||
slave->error_reported = 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (unlikely(slave->error_reported))
|
||||
slave->error_reported = 0;
|
||||
|
||||
|
|
@ -156,7 +171,7 @@ void EtherCAT_write_value(EtherCAT_slave_t *slave,
|
|||
return;
|
||||
}
|
||||
|
||||
if (unlikely(channel >= slave->desc->channels)) {
|
||||
if (unlikely(channel >= slave->desc->channel_count)) {
|
||||
if (likely(slave->error_reported)) {
|
||||
printk(KERN_WARNING "EtherCAT: Writing failed on slave %4X (addr %0X)"
|
||||
" - Type (%s %s) has no channel %i.\n",
|
||||
|
|
@ -168,6 +183,16 @@ void EtherCAT_write_value(EtherCAT_slave_t *slave,
|
|||
return;
|
||||
}
|
||||
|
||||
if (unlikely(!slave->process_data)) {
|
||||
if (likely(slave->error_reported)) {
|
||||
printk(KERN_WARNING "EtherCAT: Writing failed on slave %4X (addr %0X)"
|
||||
" - Slave does not belong to any process data object!\n",
|
||||
slave->station_address, (unsigned int) slave);
|
||||
slave->error_reported = 1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (unlikely(slave->error_reported))
|
||||
slave->error_reported = 0;
|
||||
|
||||
|
|
@ -180,3 +205,9 @@ EXPORT_SYMBOL(EtherCAT_write_value);
|
|||
EXPORT_SYMBOL(EtherCAT_read_value);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/* Emacs-Konfiguration
|
||||
;;; Local Variables: ***
|
||||
;;; c-basic-offset:2 ***
|
||||
;;; End: ***
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -42,20 +42,21 @@ typedef struct
|
|||
const EtherCAT_slave_desc_t *desc; /**< Zeiger auf die Beschreibung
|
||||
des Slave-Typs */
|
||||
|
||||
unsigned int logical_address0; /**< Konfigurierte, logische adresse */
|
||||
unsigned int logical_address; /**< Konfigurierte, logische adresse */
|
||||
|
||||
EtherCAT_state_t current_state; /**< Aktueller Zustand */
|
||||
EtherCAT_state_t requested_state; /**< Angeforderter Zustand */
|
||||
|
||||
unsigned char *process_data; /**< Zeiger auf den Speicherbereich
|
||||
im Prozessdatenspeicher des Masters */
|
||||
int error_reported; /**< Ein Zugriffsfehler wurde bereits gemeldet. */
|
||||
innerhalb eines Prozessdatenobjekts */
|
||||
unsigned int domain; /**< Prozessdatendomäne */
|
||||
int error_reported; /**< Ein Zugriffsfehler wurde bereits gemeldet */
|
||||
}
|
||||
EtherCAT_slave_t;
|
||||
|
||||
#define ECAT_INIT_SLAVE(TYPE) {0, 0, 0, 0, 0, 0, 0, 0, 0, \
|
||||
TYPE, 0, ECAT_STATE_UNKNOWN, \
|
||||
ECAT_STATE_UNKNOWN, NULL}
|
||||
#define ECAT_INIT_SLAVE(TYPE, DOMAIN) {0, 0, 0, 0, 0, 0, 0, 0, 0, \
|
||||
TYPE, 0, ECAT_STATE_UNKNOWN, \
|
||||
ECAT_STATE_UNKNOWN, NULL, DOMAIN, 0}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
@ -69,3 +70,9 @@ void EtherCAT_write_value(EtherCAT_slave_t *, unsigned int, int);
|
|||
/*****************************************************************************/
|
||||
|
||||
#endif
|
||||
|
||||
/* Emacs-Konfiguration
|
||||
;;; Local Variables: ***
|
||||
;;; c-basic-offset:2 ***
|
||||
;;; End: ***
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -57,8 +57,8 @@ typedef struct slave_desc
|
|||
const unsigned char *fmmu0; /**< Konfigurationsdaten
|
||||
der ersten FMMU */
|
||||
|
||||
const unsigned int data_length; /**< Länge der Prozessdaten in Bytes */
|
||||
const unsigned int channels; /**< Anzahl der Kanäle */
|
||||
const unsigned int process_data_size; /**< Länge der Prozessdaten in Bytes */
|
||||
const unsigned int channel_count; /**< Anzahl der Kanäle */
|
||||
|
||||
int (*read) (unsigned char *, unsigned int); /**< Funktion zum Dekodieren
|
||||
und Lesen der Kanaldaten */
|
||||
|
|
|
|||
162
mini/ec_mini.c
162
mini/ec_mini.c
|
|
@ -6,7 +6,7 @@
|
|||
*
|
||||
* $Id$
|
||||
*
|
||||
******************************************************************************/
|
||||
*****************************************************************************/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/delay.h>
|
||||
|
|
@ -17,12 +17,12 @@
|
|||
#include "../drivers/ec_types.h"
|
||||
#include "../drivers/ec_module.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
// Auskommentieren, wenn keine zyklischen Daten erwuenscht
|
||||
#define ECAT_CYCLIC_DATA
|
||||
|
||||
/******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
static EtherCAT_master_t *ecat_master = NULL;
|
||||
|
||||
|
|
@ -30,52 +30,52 @@ static EtherCAT_slave_t ecat_slaves[] =
|
|||
{
|
||||
#if 0
|
||||
// Block 1
|
||||
ECAT_INIT_SLAVE(Beckhoff_EK1100),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL4102),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL3162),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL1014),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EK1100, 1),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL4102, 1),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL3162, 1),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL1014, 1),
|
||||
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL4102),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL4102),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL4102),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL4102, 1),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL4102, 1),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL4102, 1),
|
||||
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL3162),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL3162),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL3162),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL3102),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL3102),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL3102),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL3162, 1),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL3162, 1),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL3162, 1),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL3102, 1),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL3102, 1),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL3102, 1),
|
||||
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
// Block 2
|
||||
ECAT_INIT_SLAVE(Beckhoff_EK1100),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL4102),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL1014),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL3162),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL2004),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL3102),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL2004),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL2004),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL2004),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL2004),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL2004),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EK1100, 1),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL4102, 1),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL1014, 1),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL3162, 1),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL2004, 1),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL3102, 1),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL2004, 1),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL2004, 1),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL2004, 1),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL2004, 1),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL2004, 1),
|
||||
|
||||
// Block 3
|
||||
ECAT_INIT_SLAVE(Beckhoff_EK1100),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL1014),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL1014),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL1014),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL1014),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL1014),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL2004),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL2004),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL2004),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL2004),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL1014),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL1014),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL1014)
|
||||
ECAT_INIT_SLAVE(Beckhoff_EK1100, 1),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL1014, 1),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL1014, 1),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL1014, 1),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL1014, 1),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL1014, 1),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL2004, 1),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL2004, 1),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL2004, 1),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL2004, 1),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL1014, 1),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL1014, 1),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL1014, 1)
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
@ -136,7 +136,7 @@ static int next2004(int *wrap)
|
|||
|
||||
static void run(unsigned long data)
|
||||
{
|
||||
static int ms = 0;
|
||||
static int ms = 0;
|
||||
static int cnt = 0;
|
||||
static unsigned long int k = 0;
|
||||
static int firstrun = 1;
|
||||
|
|
@ -149,37 +149,7 @@ static void run(unsigned long data)
|
|||
ms++;
|
||||
ms %= 1000;
|
||||
|
||||
#if 0
|
||||
ecat_tx_delay = ((unsigned int) (100000 / HZ) * (ecat_master->dev->tx_time-k))
|
||||
/ (current_cpu_data.loops_per_jiffy / 10);
|
||||
ecat_rx_delay = ((unsigned int) (100000 / HZ) * (ecat_master->dev->rx_time-k))
|
||||
/ (current_cpu_data.loops_per_jiffy / 10);
|
||||
|
||||
rx_intr = ecat_master->dev->rx_intr_cnt;
|
||||
tx_intr = ecat_master->dev->tx_intr_cnt;
|
||||
total_intr = ecat_master->dev->intr_cnt;
|
||||
#endif
|
||||
|
||||
// Prozessdaten lesen
|
||||
if (!firstrun)
|
||||
{
|
||||
EtherCAT_read_process_data(ecat_master);
|
||||
|
||||
// Daten lesen und skalieren
|
||||
// value = EtherCAT_read_value(&ecat_master->slaves[5], 0) / 3276; //.7; FIXME kein FP im Kernel ohne Schutz !!
|
||||
// dig1 = EtherCAT_read_value(&ecat_master->slaves[3], 0);
|
||||
}
|
||||
else
|
||||
klemme = next2004(&wrap);
|
||||
|
||||
|
||||
#if 0
|
||||
// Daten schreiben
|
||||
EtherCAT_write_value(&ecat_master->slaves[4], 0, ms > 500 ? 1 : 0);
|
||||
EtherCAT_write_value(&ecat_master->slaves[4], 1, ms > 500 ? 0 : 1);
|
||||
EtherCAT_write_value(&ecat_master->slaves[4], 2, ms > 500 ? 0 : 1);
|
||||
EtherCAT_write_value(&ecat_master->slaves[4], 3, ms > 500 ? 1 : 0);
|
||||
#endif
|
||||
if (firstrun) klemme = next2004(&wrap);
|
||||
|
||||
if (cnt++ > 20)
|
||||
{
|
||||
|
|
@ -198,20 +168,12 @@ static void run(unsigned long data)
|
|||
}
|
||||
}
|
||||
|
||||
if (klemme >= 0) {
|
||||
EtherCAT_write_value(&ecat_master->slaves[klemme], kanal,up_down);
|
||||
//printk("ECAT write: Klemme: %d, Kanal: %d, Wert: %d\n",klemme,kanal,up_down);
|
||||
}
|
||||
if (klemme >= 0)
|
||||
EtherCAT_write_value(&ecat_slaves[klemme], kanal, up_down);
|
||||
|
||||
#if 0
|
||||
EtherCAT_write_value(&ecat_master->slaves[13], 1, ms > 500 ? 0 : 1);
|
||||
EtherCAT_write_value(&ecat_master->slaves[14], 2, ms > 500 ? 0 : 1);
|
||||
EtherCAT_write_value(&ecat_master->slaves[15], 3, ms > 500 ? 1 : 0);
|
||||
#endif
|
||||
|
||||
// Prozessdaten schreiben
|
||||
// Prozessdaten lesen und schreiben
|
||||
rdtscl(k);
|
||||
EtherCAT_write_process_data(ecat_master);
|
||||
EtherCAT_process_data_cycle(ecat_master, 1);
|
||||
firstrun = 0;
|
||||
|
||||
timer.expires += HZ / 1000;
|
||||
|
|
@ -224,10 +186,12 @@ static void run(unsigned long data)
|
|||
*
|
||||
* Function: init
|
||||
*
|
||||
******************************************************************************/
|
||||
*****************************************************************************/
|
||||
|
||||
int __init init_module()
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
printk(KERN_INFO "=== Starting Minimal EtherCAT environment... ===\n");
|
||||
|
||||
if ((ecat_master = EtherCAT_request(0)) == NULL) {
|
||||
|
|
@ -237,17 +201,19 @@ int __init init_module()
|
|||
|
||||
printk("Checking EtherCAT slaves.\n");
|
||||
|
||||
if (EtherCAT_check_slaves(ecat_master, ecat_slaves, ECAT_SLAVES_COUNT) != 0) {
|
||||
if (EtherCAT_check_slaves(ecat_master, ecat_slaves,
|
||||
ECAT_SLAVES_COUNT) != 0) {
|
||||
printk(KERN_ERR "EtherCAT: Could not init slaves!\n");
|
||||
goto out_release_master;
|
||||
}
|
||||
|
||||
printk("Activating all EtherCAT slaves.\n");
|
||||
|
||||
if (EtherCAT_activate_all_slaves(ecat_master) != 0)
|
||||
{
|
||||
printk(KERN_ERR "EtherCAT: Could not activate slaves!\n");
|
||||
goto out_release_master;
|
||||
for (i = 0; i < ECAT_SLAVES_COUNT; i++) {
|
||||
if (EtherCAT_activate_slave(ecat_master, &ecat_slaves[i]) != 0) {
|
||||
printk(KERN_ERR "EtherCAT: Could not activate slave %i!\n", i);
|
||||
goto out_release_master;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ECAT_CYCLIC_DATA
|
||||
|
|
@ -279,21 +245,25 @@ int __init init_module()
|
|||
*
|
||||
* Function: cleanup
|
||||
*
|
||||
******************************************************************************/
|
||||
*****************************************************************************/
|
||||
|
||||
void __exit cleanup_module()
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
printk(KERN_INFO "=== Stopping Minimal EtherCAT environment... ===\n");
|
||||
|
||||
if (ecat_master)
|
||||
{
|
||||
#ifdef ECAT_CYCLIC_DATA
|
||||
del_timer_sync(&timer);
|
||||
EtherCAT_clear_process_data(ecat_master);
|
||||
#endif // ECAT_CYCLIC_DATA
|
||||
|
||||
printk(KERN_INFO "Deactivating slaves.\n");
|
||||
EtherCAT_deactivate_all_slaves(ecat_master);
|
||||
|
||||
for (i = 0; i < ECAT_SLAVES_COUNT; i++) {
|
||||
EtherCAT_deactivate_slave(ecat_master, &ecat_slaves[i]);
|
||||
}
|
||||
|
||||
EtherCAT_release(ecat_master);
|
||||
}
|
||||
|
|
@ -311,3 +281,9 @@ module_init(init_module);
|
|||
module_exit(cleanup_module);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/* Emacs-Konfiguration
|
||||
;;; Local Variables: ***
|
||||
;;; c-basic-offset:4 ***
|
||||
;;; End: ***
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -130,7 +130,6 @@ void msr_jitter_run(unsigned int hz) {
|
|||
|
||||
int i,hit;
|
||||
static int firstrun = 1;
|
||||
static int counter = 0;
|
||||
static unsigned long k,j = 0;
|
||||
unsigned int dt,jitter;
|
||||
|
||||
|
|
|
|||
355
rt/msr_module.c
355
rt/msr_module.c
|
|
@ -1,43 +1,23 @@
|
|||
/**************************************************************************************************
|
||||
*
|
||||
* msr_module.c
|
||||
*
|
||||
* Kernelmodul f<EFBFBD>ür 2.6 Kernel zur Me<EFBFBD>ßdatenerfassung, Steuerung und Regelung
|
||||
* Zeitgeber ist der Timerinterrupt (tq)
|
||||
*
|
||||
* Autor: Wilhelm Hagemeister
|
||||
*
|
||||
* (C) Copyright IgH 2002
|
||||
* Ingenieurgemeinschaft IgH
|
||||
* Heinz-B<EFBFBD>äcker Str. 34
|
||||
* D-45356 Essen
|
||||
* Tel.: +49 201/61 99 31
|
||||
* Fax.: +49 201/61 98 36
|
||||
* E-mail: hm@igh-essen.com
|
||||
*
|
||||
*
|
||||
* $RCSfile: msr_module.c,v $
|
||||
* $Revision: 1.1 $
|
||||
* $Author: hm $
|
||||
* $Date: 2005/11/14 20:32:57 $
|
||||
* $State: Exp $
|
||||
*
|
||||
*
|
||||
* $Log: msr_module.c,v $
|
||||
* Revision 1.1 2005/11/14 20:32:57 hm
|
||||
* Initial revision
|
||||
*
|
||||
* Revision 1.13 2005/06/17 11:35:13 hm
|
||||
* *** empty log message ***
|
||||
*
|
||||
*
|
||||
* Hello Emacs: -*- c-basic-offset: 2; -*-
|
||||
*
|
||||
**************************************************************************************************/
|
||||
|
||||
|
||||
/*--includes-------------------------------------------------------------------------------------*/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* msr_module.c
|
||||
*
|
||||
* Kernelmodul f<EFBFBD>ür 2.6 Kernel zur Me<EFBFBD>ßdatenerfassung, Steuerung und Regelung.
|
||||
* Zeitgeber ist der Timerinterrupt (tq)
|
||||
*
|
||||
* Autor: Wilhelm Hagemeister
|
||||
*
|
||||
* (C) Copyright IgH 2002
|
||||
* Ingenieurgemeinschaft IgH
|
||||
* Heinz-B<EFBFBD>äcker Str. 34
|
||||
* D-45356 Essen
|
||||
* Tel.: +49 201/61 99 31
|
||||
* Fax.: +49 201/61 98 36
|
||||
* E-mail: hm@igh-essen.com
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __KERNEL__
|
||||
# define __KERNEL__
|
||||
|
|
@ -51,7 +31,7 @@
|
|||
|
||||
#include <linux/sched.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/fs.h> /* everything... */
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/time.h>
|
||||
|
|
@ -84,12 +64,9 @@
|
|||
|
||||
#include "msr_jitter.h"
|
||||
|
||||
MODULE_AUTHOR("Wilhelm Hagemeister, Ingenieurgemeinschaft IgH");
|
||||
MODULE_LICENSE("GPL");
|
||||
#define TSC2US(T) ((unsigned long) (T) * 1000UL / cpu_khz)
|
||||
|
||||
/*--external functions---------------------------------------------------------------------------*/
|
||||
|
||||
/*--external data--------------------------------------------------------------------------------*/
|
||||
/*--external data------------------------------------------------------------*/
|
||||
|
||||
#define HZREDUCTION (MSR_ABTASTFREQUENZ/HZ)
|
||||
|
||||
|
|
@ -99,12 +76,10 @@ extern struct msr_char_buf *msr_kanal_puffer;
|
|||
|
||||
extern int proc_abtastfrequenz;
|
||||
|
||||
/*--public data----------------------------------------------------------------------------------*/
|
||||
/*--local data-----------------------------------------------------------------------------------*/
|
||||
//struct timer_list timer;
|
||||
/*--local data---------------------------------------------------------------*/
|
||||
|
||||
extern struct timeval process_time;
|
||||
struct timeval msr_time_increment; // Increment per Interrupt
|
||||
extern struct timeval process_time;
|
||||
struct timeval msr_time_increment; // Increment per Interrupt
|
||||
|
||||
//adeos
|
||||
|
||||
|
|
@ -116,55 +91,51 @@ static EtherCAT_master_t *ecat_master = NULL;
|
|||
|
||||
static EtherCAT_slave_t ecat_slaves[] =
|
||||
{
|
||||
|
||||
|
||||
#if 1
|
||||
// Block 1
|
||||
ECAT_INIT_SLAVE(Beckhoff_EK1100),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL4102),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL1014),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL3162),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL2004),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL3102),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL2004),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL2004),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL2004),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL2004),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL2004),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EK1100, 0),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL4102, 0),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL1014, 0),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL3162, 0),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL2004, 0),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL3102, 0),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL2004, 0),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL2004, 0),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL2004, 0),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL2004, 0),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL2004, 0),
|
||||
|
||||
// Block 2
|
||||
ECAT_INIT_SLAVE(Beckhoff_EK1100),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL1014),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL1014),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL1014),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL1014),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL1014),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL2004),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL2004),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL2004),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL2004),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL1014),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL1014),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL1014)
|
||||
ECAT_INIT_SLAVE(Beckhoff_EK1100, 1),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL1014, 1),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL1014, 1),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL1014, 1),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL1014, 1),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL1014, 1),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL2004, 1),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL2004, 1),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL2004, 1),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL2004, 1),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL1014, 1),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL1014, 1),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL1014, 1)
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
#if 0
|
||||
// Block 3
|
||||
,ECAT_INIT_SLAVE(Beckhoff_EK1100),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL3162),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL3162),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL3162),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL3162),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL3102),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL3102),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL3102),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL4102),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL4102),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL4102),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL4102),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL4132)
|
||||
|
||||
|
||||
,ECAT_INIT_SLAVE(Beckhoff_EK1100, 2),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL3162, 2),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL3162, 2),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL3162, 2),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL3162, 2),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL3102, 2),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL3102, 2),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL3102, 2),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL4102, 2),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL4102, 2),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL4102, 2),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL4102, 2),
|
||||
ECAT_INIT_SLAVE(Beckhoff_EL4132, 2)
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
@ -183,8 +154,6 @@ int dig1;
|
|||
*
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
static int next2004(int *wrap)
|
||||
{
|
||||
static int i = 0;
|
||||
|
|
@ -228,23 +197,17 @@ static void msr_controller_run(void)
|
|||
static int up_down = 0;
|
||||
int wrap = 0;
|
||||
|
||||
static unsigned int debug_counter = 0;
|
||||
unsigned long t1, t2, t3, t4, t5, t6, t7;
|
||||
static unsigned long lt = 0;
|
||||
unsigned int tr1, tr2;
|
||||
|
||||
rdtscl(t1);
|
||||
|
||||
// Prozessdaten lesen
|
||||
msr_jitter_run(MSR_ABTASTFREQUENZ);
|
||||
|
||||
if (!firstrun)
|
||||
{
|
||||
EtherCAT_read_process_data(ecat_master);
|
||||
|
||||
// Daten lesen und skalieren
|
||||
#ifdef USE_MSR_LIB
|
||||
value = EtherCAT_read_value(&ecat_master->slaves[5], 0) / 3276.0;
|
||||
dig1 = EtherCAT_read_value(&ecat_master->slaves[2], 0);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
klemme = next2004(&wrap);
|
||||
|
||||
if (firstrun) klemme = next2004(&wrap);
|
||||
|
||||
ms++;
|
||||
ms %= 1000;
|
||||
|
|
@ -266,8 +229,7 @@ static void msr_controller_run(void)
|
|||
}
|
||||
|
||||
if (klemme >= 0) {
|
||||
EtherCAT_write_value(&ecat_master->slaves[klemme], kanal,up_down);
|
||||
//printk("ECAT write: Klemme: %d, Kanal: %d, Wert: %d\n",klemme,kanal,up_down);
|
||||
EtherCAT_write_value(&ecat_slaves[klemme], kanal, up_down);
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
|
@ -278,32 +240,63 @@ static void msr_controller_run(void)
|
|||
|
||||
// Prozessdaten schreiben
|
||||
rdtscl(k);
|
||||
EtherCAT_write_process_data(ecat_master);
|
||||
firstrun = 0;
|
||||
rdtscl(t2);
|
||||
|
||||
EtherCAT_process_data_cycle(ecat_master, 0);
|
||||
|
||||
t3 = ecat_master->tx_time;
|
||||
t4 = ecat_master->rx_time;
|
||||
tr1 = ecat_master->rx_tries;
|
||||
|
||||
EtherCAT_process_data_cycle(ecat_master, 1);
|
||||
|
||||
t5 = ecat_master->tx_time;
|
||||
t6 = ecat_master->rx_time;
|
||||
tr2 = ecat_master->rx_tries;
|
||||
|
||||
//EtherCAT_process_data_cycle(ecat_master, 2);
|
||||
|
||||
// Daten lesen und skalieren
|
||||
#ifdef USE_MSR_LIB
|
||||
value = EtherCAT_read_value(&ecat_slaves[5], 0) / 3276.0;
|
||||
dig1 = EtherCAT_read_value(&ecat_slaves[2], 0);
|
||||
#endif
|
||||
|
||||
rdtscl(t7);
|
||||
|
||||
if (debug_counter == MSR_ABTASTFREQUENZ) {
|
||||
printk(KERN_DEBUG "%lu: %lu޵s + %lu޵s + %lu޵s + %lu޵s + %lu޵s +"
|
||||
" %lu޵s = %lu޵s (%u %u)\n",
|
||||
TSC2US(t1 - lt),
|
||||
TSC2US(t2 - t1), TSC2US(t3 - t2), TSC2US(t4 - t3),
|
||||
TSC2US(t5 - t4), TSC2US(t6 - t5), TSC2US(t7 - t6),
|
||||
TSC2US(t7 - t1), tr1, tr2);
|
||||
debug_counter = 0;
|
||||
}
|
||||
|
||||
lt = t1;
|
||||
|
||||
firstrun = 0;
|
||||
debug_counter++;
|
||||
}
|
||||
|
||||
/*
|
||||
***************************************************************************************************
|
||||
*
|
||||
* Function: msr_run(_interrupt)
|
||||
*
|
||||
* Beschreibung: Routine wird zyklisch im Timerinterrupt ausgef<EFBFBD>ührt
|
||||
* (hier mu<EFBFBD>ß alles rein, was Echtzeit ist ...)
|
||||
*
|
||||
* Parameter: Zeiger auf msr_data
|
||||
*
|
||||
* R<EFBFBD>ückgabe:
|
||||
*
|
||||
* Status: exp
|
||||
*
|
||||
***************************************************************************************************
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Function: msr_run(_interrupt)
|
||||
*
|
||||
* Beschreibung: Routine wird zyklisch im Timerinterrupt ausgef<EFBFBD>ührt
|
||||
* (hier mu<EFBFBD>ß alles rein, was Echtzeit ist ...)
|
||||
*
|
||||
* Parameter: Zeiger auf msr_data
|
||||
*
|
||||
* R<EFBFBD>ückgabe:
|
||||
*
|
||||
* Status: exp
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
void msr_run(unsigned irq)
|
||||
{
|
||||
|
||||
static int counter = 0;
|
||||
#ifdef USE_MSR_LIB
|
||||
|
||||
|
|
@ -318,45 +311,40 @@ void msr_run(unsigned irq)
|
|||
#endif
|
||||
/* und wieder in die Timerliste eintragen */
|
||||
/* und neu in die Taskqueue eintragen */
|
||||
// timer.expires += 1;
|
||||
// add_timer(&timer);
|
||||
//timer.expires += 1;
|
||||
//add_timer(&timer);
|
||||
|
||||
ipipe_control_irq(irq,0,IPIPE_ENABLE_MASK); //Interrupt bestŽätigen
|
||||
if(counter++ > HZREDUCTION) {
|
||||
ipipe_propagate_irq(irq); //und weiterreichen
|
||||
counter = 0;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void domain_entry (void) {
|
||||
printk("Domain %s started.\n", ipipe_current_domain->name);
|
||||
|
||||
void domain_entry (void)
|
||||
{
|
||||
printk("Domain %s started.\n", ipipe_current_domain->name);
|
||||
|
||||
ipipe_get_sysinfo(&sys_info);
|
||||
ipipe_virtualize_irq(ipipe_current_domain,sys_info.archdep.tmirq,
|
||||
&msr_run, NULL, IPIPE_HANDLE_MASK);
|
||||
|
||||
ipipe_tune_timer(1000000000UL/MSR_ABTASTFREQUENZ,0);
|
||||
|
||||
ipipe_tune_timer(1000000000UL/MSR_ABTASTFREQUENZ,0);
|
||||
}
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
*
|
||||
* Function: msr_register_channels
|
||||
*
|
||||
* Beschreibung: KanŽäle registrieren
|
||||
*
|
||||
* Parameter:
|
||||
*
|
||||
* RŽückgabe:
|
||||
*
|
||||
* Status: exp
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
/******************************************************************************
|
||||
*
|
||||
* Function: msr_register_channels
|
||||
*
|
||||
* Beschreibung: KanŽäle registrieren
|
||||
*
|
||||
* Parameter:
|
||||
*
|
||||
* RŽückgabe:
|
||||
*
|
||||
* Status: exp
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
int msr_globals_register(void)
|
||||
{
|
||||
|
|
@ -364,23 +352,23 @@ int msr_globals_register(void)
|
|||
msr_reg_kanal("/value", "V", &value, TDBL);
|
||||
msr_reg_kanal("/dig1", "", &dig1, TINT);
|
||||
#endif
|
||||
/* msr_reg_kanal("/Taskinfo/Ecat/TX-Delay","us",&ecat_tx_delay,TUINT);
|
||||
msr_reg_kanal("/Taskinfo/Ecat/RX-Delay","us",&ecat_rx_delay,TUINT);
|
||||
msr_reg_kanal("/Taskinfo/Ecat/TX-Cnt","",&tx_intr,TUINT);
|
||||
msr_reg_kanal("/Taskinfo/Ecat/RX-Cnt","",&rx_intr,TUINT);
|
||||
msr_reg_kanal("/Taskinfo/Ecat/Total-Cnt","",&total_intr,TUINT);
|
||||
*/
|
||||
#if 0
|
||||
msr_reg_kanal("/Taskinfo/Ecat/TX-Delay","us",&ecat_tx_delay,TUINT);
|
||||
msr_reg_kanal("/Taskinfo/Ecat/RX-Delay","us",&ecat_rx_delay,TUINT);
|
||||
msr_reg_kanal("/Taskinfo/Ecat/TX-Cnt","",&tx_intr,TUINT);
|
||||
msr_reg_kanal("/Taskinfo/Ecat/RX-Cnt","",&rx_intr,TUINT);
|
||||
msr_reg_kanal("/Taskinfo/Ecat/Total-Cnt","",&total_intr,TUINT);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************************************
|
||||
/******************************************************************************
|
||||
* the init/clean material
|
||||
****************************************************************************************************/
|
||||
|
||||
*****************************************************************************/
|
||||
|
||||
int __init init_module()
|
||||
{
|
||||
unsigned int i;
|
||||
struct ipipe_domain_attr attr; //ipipe
|
||||
|
||||
// Als allererstes die RT-lib initialisieren
|
||||
|
|
@ -409,9 +397,10 @@ int __init init_module()
|
|||
|
||||
printk("Activating all EtherCAT slaves.\n");
|
||||
|
||||
if (EtherCAT_activate_all_slaves(ecat_master) != 0) {
|
||||
printk(KERN_ERR "EtherCAT: Could not activate slaves!\n");
|
||||
goto out_release_master;
|
||||
for (i = 0; i < ECAT_SLAVES_COUNT; i++) {
|
||||
if (EtherCAT_activate_slave(ecat_master, ecat_slaves + i) < 0) {
|
||||
goto out_release_master;
|
||||
}
|
||||
}
|
||||
|
||||
do_gettimeofday(&process_time);
|
||||
|
|
@ -436,11 +425,12 @@ int __init init_module()
|
|||
return -1;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
void __exit cleanup_module()
|
||||
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
msr_print_info("msk_modul: unloading...");
|
||||
|
||||
ipipe_tune_timer(1000000000UL/HZ,0); //alten Timertakt wieder herstellen
|
||||
|
|
@ -450,9 +440,14 @@ void __exit cleanup_module()
|
|||
|
||||
if (ecat_master)
|
||||
{
|
||||
EtherCAT_clear_process_data(ecat_master);
|
||||
printk(KERN_INFO "Deactivating slaves.\n");
|
||||
EtherCAT_deactivate_all_slaves(ecat_master);
|
||||
|
||||
for (i = 0; i < ECAT_SLAVES_COUNT; i++) {
|
||||
if (EtherCAT_deactivate_slave(ecat_master, ecat_slaves + i) < 0) {
|
||||
printk(KERN_WARNING "Warning - Could not deactivate slave!\n");
|
||||
}
|
||||
}
|
||||
|
||||
EtherCAT_release(ecat_master);
|
||||
}
|
||||
|
||||
|
|
@ -463,6 +458,8 @@ void __exit cleanup_module()
|
|||
#endif
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR ("Wilhelm Hagemeister <hm@igh-essen.com>");
|
||||
MODULE_DESCRIPTION ("EtherCAT test environment");
|
||||
|
|
@ -470,18 +467,4 @@ MODULE_DESCRIPTION ("EtherCAT test environment");
|
|||
module_init(init_module);
|
||||
module_exit(cleanup_module);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#ifndef _MSR_PARAM_H_
|
||||
#define _MSR_PARAM_H_
|
||||
#define MSR_ABTASTFREQUENZ 20000 //FIXME nur für den Simulator, der virtuelle 10 Mal schneller läuft ....HZ /* Abtastrate der Kan%/1€Œiso8859-15<02>äle in [HZ]*/
|
||||
#define MSR_ABTASTFREQUENZ 10000 //FIXME nur für den Simulator, der virtuelle 10 Mal schneller läuft ....HZ /* Abtastrate der Kan%/1€Œiso8859-15<02>äle in [HZ]*/
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue