diff --git a/drivers/ec_command.c b/drivers/ec_command.c index d18b51200b51e76f538807c2187d4a05a261fda1..f8cb2677ae576172d3da443c18c64068f8fdcea5 100644 --- a/drivers/ec_command.c +++ b/drivers/ec_command.c @@ -112,7 +112,7 @@ void EtherCAT_command_write(EtherCAT_command_t *cmd, const unsigned char *data) { if (node_address == 0x0000) - EC_DBG(KERN_WARNING "WARNING: Using node address 0x0000!\n"); + EC_DBG(KERN_WARNING "EtherCAT: Using node address 0x0000!\n"); ECAT_FUNC_HEADER; diff --git a/drivers/ec_device.c b/drivers/ec_device.c index 02aefe31c6466c11544f2a139a004f9d81405171..ce2e973f48cda6da5114605c78ca75d64b841116 100644 --- a/drivers/ec_device.c +++ b/drivers/ec_device.c @@ -253,28 +253,30 @@ int EtherCAT_device_send(EtherCAT_device_t *ecd, @param ecd EtherCAT-Gerät @param data Zeiger auf den Speicherbereich, in den die - empfangenen Daten kopiert werden sollen - @param size Größe des angegebenen Speicherbereichs + empfangenen Daten kopiert werden sollen @return Anzahl der kopierten Bytes bei Erfolg, sonst < 0 */ int EtherCAT_device_receive(EtherCAT_device_t *ecd, - unsigned char *data, - unsigned int size) + unsigned char *data) { - int cnt; - if (ecd->state != ECAT_DS_RECEIVED) { EC_DBG(KERN_ERR "EtherCAT: receive - Nothing received!\n"); return -1; } - cnt = min(ecd->rx_data_length, size); - memcpy(data,ecd->rx_data, cnt); + if (ecd->rx_data_length > ECAT_FRAME_BUFFER_SIZE) + { + EC_DBG(KERN_ERR "EtherCAT: receive - Reveived frame too long (%i Bytes)!\n", + ecd->rx_data_length); + return -1; + } + + memcpy(data, ecd->rx_data, ecd->rx_data_length); - return cnt; + return ecd->rx_data_length; } /***************************************************************/ diff --git a/drivers/ec_device.h b/drivers/ec_device.h index 9b79b55b132da1cfb9d4d7e627273e2a826c1053..6ef45f7d47c243ef2c89ac5f291c5fdec4870913 100644 --- a/drivers/ec_device.h +++ b/drivers/ec_device.h @@ -77,7 +77,7 @@ int EtherCAT_device_open(EtherCAT_device_t *); int EtherCAT_device_close(EtherCAT_device_t *); int EtherCAT_device_send(EtherCAT_device_t *, unsigned char *, unsigned int); -int EtherCAT_device_receive(EtherCAT_device_t *, unsigned char *, unsigned int); +int EtherCAT_device_receive(EtherCAT_device_t *, unsigned char *); void EtherCAT_device_call_isr(EtherCAT_device_t *); void EtherCAT_device_debug(EtherCAT_device_t *); diff --git a/drivers/ec_globals.h b/drivers/ec_globals.h index 4b54729cdd168d5d9c088ee5e4f0c3d87ce82454..0ddf503372c23406d3702daf66e2cf81eb8bcdcd 100644 --- a/drivers/ec_globals.h +++ b/drivers/ec_globals.h @@ -15,17 +15,7 @@ /** Maximale Größe eines EtherCAT-Frames */ -#define ECAT_FRAME_BUFFER_SIZE 1600 - -/** - Anzahl der Kommandos in einem Master-Kommandoring -*/ -#define ECAT_COMMAND_RING_SIZE 10 - -/** - Anzahl der Versuche beim Asynchronen Senden/Empfangen -*/ -#define ECAT_NUM_RETRIES 10 +#define ECAT_FRAME_BUFFER_SIZE 1500 /** NULL-Define, falls noch nicht definiert. diff --git a/drivers/ec_master.c b/drivers/ec_master.c index d8b078ef588a93894762ef3f9ff3a3d43f4fa652..433493358cf523facf648217218197f933a2d915 100644 --- a/drivers/ec_master.c +++ b/drivers/ec_master.c @@ -25,7 +25,7 @@ @param master Zeiger auf den zu initialisierenden EtherCAT-Master - @param dev Zeiger auf das EtherCAT-gerät, mit dem der + @param dev Zeiger auf das EtherCAT-Gerät, mit dem der Master arbeiten soll @return 0 bei Erfolg, sonst < 0 (= dev ist NULL) @@ -96,10 +96,12 @@ int EtherCAT_simple_send_receive(EtherCAT_master_t *master, if (EtherCAT_simple_send(master, cmd) < 0) return -1; - tries_left = 100; - while (cmd->state == ECAT_CS_SENT && tries_left) + EtherCAT_device_call_isr(master->dev); + + tries_left = 1000; + while (master->dev->state == ECAT_DS_SENT && tries_left) { - udelay(10); + udelay(1); EtherCAT_device_call_isr(master->dev); tries_left--; } @@ -137,6 +139,13 @@ int EtherCAT_simple_send(EtherCAT_master_t *master, length = cmd->data_length + 12; framelength = length + 2; + + if (framelength > ECAT_FRAME_BUFFER_SIZE) + { + EC_DBG(KERN_ERR "EtherCAT: Frame too long (%i)!\n", framelength); + return -1; + } + if (framelength < 46) framelength = 46; if (master->debug_level > 0) @@ -223,32 +232,32 @@ int EtherCAT_simple_send(EtherCAT_master_t *master, int EtherCAT_simple_receive(EtherCAT_master_t *master, EtherCAT_command_t *cmd) { - unsigned int rx_data_length, length; + unsigned int length; + int receive_ret; unsigned char command_type, command_index; - rx_data_length = EtherCAT_device_receive(master->dev, master->rx_data, - ECAT_FRAME_BUFFER_SIZE); + if ((receive_ret = EtherCAT_device_receive(master->dev, + master->rx_data)) < 0) + { + return -1; + } + + master->rx_data_length = (unsigned int) receive_ret; - if (rx_data_length < 2) + if (master->rx_data_length < 2) { EC_DBG(KERN_ERR "EtherCAT: Received frame with incomplete EtherCAT header!\n"); - EC_DBG(KERN_DEBUG "EtherCAT: tx_data content:\n"); - output_debug_data(master->tx_data, master->tx_data_length); - EC_DBG(KERN_DEBUG "EtherCAT: rx_data content:\n"); - output_debug_data(master->rx_data, rx_data_length); + output_debug_data(master); return -1; } // Länge des gesamten Frames prüfen length = ((master->rx_data[1] & 0x07) << 8) | (master->rx_data[0] & 0xFF); - if (length > rx_data_length) + if (length > master->rx_data_length) { EC_DBG(KERN_ERR "EtherCAT: Received corrupted frame (length does not match)!\n"); - EC_DBG(KERN_DEBUG "EtherCAT: tx_data content:\n"); - output_debug_data(master->tx_data, master->tx_data_length); - EC_DBG(KERN_DEBUG "EtherCAT: rx_data content:\n"); - output_debug_data(master->rx_data, rx_data_length); + output_debug_data(master); return -1; } @@ -256,13 +265,10 @@ int EtherCAT_simple_receive(EtherCAT_master_t *master, command_index = master->rx_data[2 + 1]; length = (master->rx_data[2 + 6] & 0xFF) | ((master->rx_data[2 + 7] & 0x07) << 8); - if (rx_data_length - 2 < length + 12) + if (master->rx_data_length - 2 < length + 12) { EC_DBG(KERN_ERR "EtherCAT: Received frame with incomplete command data!\n"); - EC_DBG(KERN_DEBUG "EtherCAT: tx_data content:\n"); - output_debug_data(master->tx_data, master->tx_data_length); - EC_DBG(KERN_DEBUG "EtherCAT: rx_data content:\n"); - output_debug_data(master->rx_data, rx_data_length); + output_debug_data(master); return -1; } @@ -283,10 +289,7 @@ int EtherCAT_simple_receive(EtherCAT_master_t *master, else { EC_DBG(KERN_WARNING "EtherCAT: WARNING - Send/Receive anomaly!\n"); - EC_DBG(KERN_DEBUG "EtherCAT: tx_data content:\n"); - output_debug_data(master->tx_data, master->tx_data_length); - EC_DBG(KERN_DEBUG "EtherCAT: rx_data content:\n"); - output_debug_data(master->rx_data, rx_data_length); + output_debug_data(master); } master->dev->state = ECAT_DS_READY; @@ -991,8 +994,24 @@ int EtherCAT_write_process_data(EtherCAT_master_t *master) int EtherCAT_read_process_data(EtherCAT_master_t *master) { + unsigned int tries_left; + EtherCAT_device_call_isr(master->dev); + tries_left = 1000; + while (master->dev->state == ECAT_DS_SENT && tries_left) + { + udelay(1); + EtherCAT_device_call_isr(master->dev); + tries_left--; + } + + if (!tries_left) + { + EC_DBG(KERN_ERR "EtherCAT: Timeout while receiving process data!\n"); + return -1; + } + if (EtherCAT_simple_receive(master, &master->process_data_command) < 0) { EC_DBG(KERN_ERR "EtherCAT: Could not receive cyclic command!\n"); @@ -1028,41 +1047,6 @@ void EtherCAT_clear_process_data(EtherCAT_master_t *master) /***************************************************************/ -/** - Setzt einen Byte-Wert im Speicher. - - @param data Startadresse - @param offset Byte-Offset - @param value Wert -*/ - -void set_byte(unsigned char *data, - unsigned int offset, - unsigned char value) -{ - data[offset] = value; -} - -/***************************************************************/ - -/** - Setzt einen Word-Wert im Speicher. - - @param data Startadresse - @param offset Byte-Offset - @param value Wert -*/ - -void set_word(unsigned char *data, - unsigned int offset, - unsigned int value) -{ - data[offset] = value & 0xFF; - data[offset + 1] = (value & 0xFF00) >> 8; -} - -/***************************************************************/ - /** Gibt Frame-Inhalte zwecks Debugging aus. @@ -1070,14 +1054,28 @@ void set_word(unsigned char *data, @param length Länge der Daten */ -void output_debug_data(unsigned char *data, unsigned int length) +void output_debug_data(const EtherCAT_master_t *master) { unsigned int i; + EC_DBG(KERN_DEBUG "EtherCAT: tx_data content (%i Bytes):\n", + master->tx_data_length); + + EC_DBG(KERN_DEBUG); + for (i = 0; i < master->tx_data_length; i++) + { + EC_DBG("%02X ", master->tx_data[i]); + if ((i + 1) % 16 == 0) EC_DBG("\n" KERN_DEBUG); + } + EC_DBG("\n"); + + EC_DBG(KERN_DEBUG "EtherCAT: rx_data content (%i Bytes):\n", + master->rx_data_length); + EC_DBG(KERN_DEBUG); - for (i = 0; i < length; i++) + for (i = 0; i < master->rx_data_length; i++) { - EC_DBG("%02X ", data[i]); + EC_DBG("%02X ", master->rx_data[i]); if ((i + 1) % 16 == 0) EC_DBG("\n" KERN_DEBUG); } EC_DBG("\n"); diff --git a/drivers/ec_master.h b/drivers/ec_master.h index 3b65a9db8e1b2e550eb340e139417f4cca457448..93224beacb1b48617038e4f5ea39e25eb6fa0963 100644 --- a/drivers/ec_master.h +++ b/drivers/ec_master.h @@ -44,6 +44,7 @@ typedef struct unsigned char rx_data[ECAT_FRAME_BUFFER_SIZE]; /**< Statische Speicher für 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 */ @@ -82,9 +83,7 @@ int EtherCAT_read_process_data(EtherCAT_master_t *); void EtherCAT_clear_process_data(EtherCAT_master_t *); // Private functions -void set_byte(unsigned char *, unsigned int, unsigned char); -void set_word(unsigned char *, unsigned int, unsigned int); -void output_debug_data(unsigned char *, unsigned int); +void output_debug_data(const EtherCAT_master_t *); /***************************************************************/