From 4e90e0b3cb16d740480331a51388b356fec6f3b3 Mon Sep 17 00:00:00 2001 From: Florian Pose <fp@igh-essen.com> Date: Fri, 24 Feb 2006 10:19:26 +0000 Subject: [PATCH] EC_READ/WRITE-Makros verwenden Makros aud asm/byteorder.h und werden konsequent verwendet. --- include/EtherCAT_rt.h | 8 +++--- include/EtherCAT_si.h | 41 +++++++++--------------------- master/canopen.c | 52 ++++++++++++++++---------------------- master/frame.c | 59 +++++++++++++++++-------------------------- master/frame.h | 3 +-- master/master.c | 46 +++++++++++++-------------------- master/slave.c | 55 ++++++++++++++++++---------------------- 7 files changed, 105 insertions(+), 159 deletions(-) diff --git a/include/EtherCAT_rt.h b/include/EtherCAT_rt.h index 280690d5..a0eb8fe2 100644 --- a/include/EtherCAT_rt.h +++ b/include/EtherCAT_rt.h @@ -87,10 +87,10 @@ int EtherCAT_rt_domain_xio(ec_domain_t *domain); // Slave Methods int EtherCAT_rt_canopen_sdo_write(ec_slave_t *slave, - unsigned int sdo_index, - unsigned char sdo_subindex, - unsigned int value, - unsigned int size); + uint16_t sdo_index, + uint8_t sdo_subindex, + uint32_t value, + size_t size); /*****************************************************************************/ diff --git a/include/EtherCAT_si.h b/include/EtherCAT_si.h index 54f69e6c..744994f7 100644 --- a/include/EtherCAT_si.h +++ b/include/EtherCAT_si.h @@ -8,6 +8,8 @@ * *****************************************************************************/ +#include <asm/byteorder.h> + /*****************************************************************************/ // Bitwise read/write macros @@ -24,31 +26,14 @@ // Read macros -#define EC_READ_U8(PD) \ - (*((uint8_t *) (PD))) - -#define EC_READ_S8(PD) \ - ((int8_t) *((uint8_t *) (PD))) - -#define EC_READ_U16(PD) \ - ((uint16_t) (*((uint8_t *) (PD) + 0) << 0 | \ - *((uint8_t *) (PD) + 1) << 8)) - -#define EC_READ_S16(PD) \ - ((int16_t) (*((uint8_t *) (PD) + 0) << 0 | \ - *((uint8_t *) (PD) + 1) << 8)) +#define EC_READ_U8(PD) ((uint8_t) *((uint8_t *) (PD))) +#define EC_READ_S8(PD) ((int8_t) *((uint8_t *) (PD))) -#define EC_READ_U32(PD) \ - ((uint32_t) (*((uint8_t *) (PD) + 0) << 0 | \ - *((uint8_t *) (PD) + 1) << 8 | \ - *((uint8_t *) (PD) + 2) << 16 | \ - *((uint8_t *) (PD) + 3) << 24)) +#define EC_READ_U16(PD) ((uint16_t) le16_to_cpup((void *) (PD))) +#define EC_READ_S16(PD) ((int16_t) le16_to_cpup((void *) (PD))) -#define EC_READ_S32(PD) \ - ((int32_t) (*((uint8_t *) (PD) + 0) << 0 | \ - *((uint8_t *) (PD) + 1) << 8 | \ - *((uint8_t *) (PD) + 2) << 16 | \ - *((uint8_t *) (PD) + 3) << 24)) +#define EC_READ_U32(PD) ((uint32_t) le32_to_cpup((void *) (PD))) +#define EC_READ_S32(PD) ((int32_t) le32_to_cpup((void *) (PD))) /*****************************************************************************/ @@ -63,18 +48,16 @@ #define EC_WRITE_U16(PD, VAL) \ do { \ - *((uint8_t *) (PD) + 0) = ((uint16_t) (VAL) >> 0) & 0xFF; \ - *((uint8_t *) (PD) + 1) = ((uint16_t) (VAL) >> 8) & 0xFF; \ + *((uint16_t *) (PD)) = (uint16_t) (VAL); \ + cpu_to_le16s(PD); \ } while (0) #define EC_WRITE_S16(PD, VAL) EC_WRITE_U16(PD, VAL) #define EC_WRITE_U32(PD, VAL) \ do { \ - *((uint8_t *) (PD) + 0) = ((uint32_t) (VAL) >> 0) & 0xFF; \ - *((uint8_t *) (PD) + 1) = ((uint32_t) (VAL) >> 8) & 0xFF; \ - *((uint8_t *) (PD) + 2) = ((uint32_t) (VAL) >> 16) & 0xFF; \ - *((uint8_t *) (PD) + 3) = ((uint32_t) (VAL) >> 24) & 0xFF; \ + *((uint32_t *) (PD)) = (uint32_t) (VAL); \ + cpu_to_le16s(PD); \ } while (0) #define EC_WRITE_S32(PD, VAL) EC_WRITE_U32(PD, VAL) diff --git a/master/canopen.c b/master/canopen.c index 94fbaf99..ffbc77d2 100644 --- a/master/canopen.c +++ b/master/canopen.c @@ -10,6 +10,7 @@ #include <linux/delay.h> +#include "../include/EtherCAT_si.h" #include "master.h" /*****************************************************************************/ @@ -22,13 +23,12 @@ Schreibt ein CANopen-SDO (service data object). */ -int EtherCAT_rt_canopen_sdo_write( - ec_slave_t *slave, /**< EtherCAT-Slave */ - unsigned int sdo_index, /**< SDO-Index */ - unsigned char sdo_subindex, /**< SDO-Subindex */ - unsigned int value, /**< Neuer Wert */ - unsigned int size /**< Größe des Datenfeldes */ - ) +int EtherCAT_rt_canopen_sdo_write(ec_slave_t *slave, /**< EtherCAT-Slave */ + uint16_t sdo_index, /**< SDO-Index */ + uint8_t sdo_subindex, /**< SDO-Subindex */ + uint32_t value, /**< Neuer Wert */ + size_t size /**< Größe des Datenfeldes */ + ) { unsigned char data[0xF6]; ec_frame_t frame; @@ -44,24 +44,17 @@ int EtherCAT_rt_canopen_sdo_write( return -1; } - data[0] = 0x0A; // Length of the Mailbox service data - data[1] = 0x00; - data[2] = slave->station_address & 0xFF; // Station address - data[3] = (slave->station_address >> 8) & 0xFF; - data[4] = 0x00; // Channel & priority - data[5] = 0x03; // CANopen over EtherCAT - data[6] = 0x00; // Number(7-0) - data[7] = 0x2 << 4; // Number(8) & Service = SDO Request (0x02) - data[8] = 0x01 // Size specified - | (0x1 << 1) // Transfer type = Expedited - | ((4 - size) << 2) // Data Set Size - | (0x1 << 5); // Command specifier = Initiate download request (0x01) - data[9] = sdo_index & 0xFF; - data[10] = (sdo_index >> 8) & 0xFF; - data[11] = sdo_subindex; + EC_WRITE_U16(data, 0x000A); // Length of the Mailbox service data + EC_WRITE_U16(data + 2, slave->station_address); // Station address + EC_WRITE_U8 (data + 4, 0x00); // Channel & priority + EC_WRITE_U8 (data + 5, 0x03); // CANopen over EtherCAT + EC_WRITE_U16(data + 6, 0x2000); // Number & Service + EC_WRITE_U8 (data + 8, 0x13 | ((4 - size) << 2)); // Spec., exp., init. + EC_WRITE_U16(data + 9, sdo_index); + EC_WRITE_U8 (data + 11, sdo_subindex); for (i = 0; i < size; i++) { - data[12 + i] = value & 0xFF; + EC_WRITE_U8(data + 12 + i, value & 0xFF); value >>= 8; } @@ -91,7 +84,7 @@ int EtherCAT_rt_canopen_sdo_write( return -1; } - if (frame.data[5] & 8) { // Written bit is high + if (EC_READ_U8(frame.data + 5) & 8) { // Written bit is high break; } @@ -115,12 +108,11 @@ int EtherCAT_rt_canopen_sdo_write( return -1; } - if (frame.data[5] != 0x03 // COE - || (frame.data[7] >> 4) != 0x03 // SDO response - || (frame.data[8] >> 5) != 0x03 // Initiate download response - || (frame.data[9] != (sdo_index & 0xFF)) // Index - || (frame.data[10] != ((sdo_index >> 8) & 0xFF)) - || (frame.data[11] != sdo_subindex)) // Subindex + if (EC_READ_U8 (frame.data + 5) != 0x03 || // COE + EC_READ_U16(frame.data + 6) != 0x3000 || // SDO response + EC_READ_U8 (frame.data + 8) >> 5 != 0x03 || // Download response + EC_READ_U16(frame.data + 9) != sdo_index || // Index + EC_READ_U8 (frame.data + 11) != sdo_subindex) // Subindex { printk(KERN_ERR "EtherCAT: Illegal mailbox response at slave %i!\n", slave->ring_position); diff --git a/master/frame.c b/master/frame.c index 65a3c0be..d3146c31 100644 --- a/master/frame.c +++ b/master/frame.c @@ -11,6 +11,7 @@ #include <linux/slab.h> #include <linux/delay.h> +#include "../include/EtherCAT_si.h" #include "frame.h" #include "master.h" @@ -27,7 +28,8 @@ memcpy(frame->data, data, length); #define EC_FUNC_READ_FOOTER \ - frame->data_length = length; + frame->data_length = length; \ + memset(frame->data, 0x00, length); /*****************************************************************************/ @@ -289,45 +291,30 @@ int ec_frame_send(ec_frame_t *frame /**< Rahmen zum Senden */) data = ec_device_prepare(&frame->master->device); // EtherCAT frame header - data[0] = command_size & 0xFF; - data[1] = ((command_size & 0x700) >> 8) | 0x10; + EC_WRITE_U16(data, (command_size & 0x7FF) | 0x1000); data += EC_FRAME_HEADER_SIZE; // EtherCAT command header - data[0] = frame->type; - data[1] = frame->index; - data[2] = frame->address.raw[0]; - data[3] = frame->address.raw[1]; - data[4] = frame->address.raw[2]; - data[5] = frame->address.raw[3]; - data[6] = frame->data_length & 0xFF; - data[7] = (frame->data_length & 0x700) >> 8; - data[8] = 0x00; - data[9] = 0x00; + EC_WRITE_U8 (data, frame->type); + EC_WRITE_U8 (data + 1, frame->index); + EC_WRITE_U32(data + 2, frame->address.logical); + EC_WRITE_U16(data + 6, frame->data_length & 0x7FF); + EC_WRITE_U16(data + 8, 0x0000); data += EC_COMMAND_HEADER_SIZE; - if (likely(frame->type == ec_frame_type_apwr // Write commands - || frame->type == ec_frame_type_npwr - || frame->type == ec_frame_type_bwr - || frame->type == ec_frame_type_lrw)) { - memcpy(data, frame->data, frame->data_length); - } - else { // Read commands - memset(data, 0x00, frame->data_length); - } + // EtherCAT command data + memcpy(data, frame->data, frame->data_length); + data += frame->data_length; // EtherCAT command footer - data += frame->data_length; - data[0] = frame->working_counter & 0xFF; - data[1] = (frame->working_counter & 0xFF00) >> 8; + EC_WRITE_U16(data, frame->working_counter); data += EC_COMMAND_FOOTER_SIZE; // Pad with zeros for (i = EC_FRAME_HEADER_SIZE + EC_COMMAND_HEADER_SIZE + frame->data_length + EC_COMMAND_FOOTER_SIZE; - i < EC_MIN_FRAME_SIZE; i++) { - *data++ = 0x00; - } + i < EC_MIN_FRAME_SIZE; i++) + EC_WRITE_U8(data++, 0x00); // Send frame ec_device_send(&frame->master->device, frame_size); @@ -371,7 +358,8 @@ int ec_frame_receive(ec_frame_t *frame /**< Gesendeter Rahmen */) data = ec_device_data(device); // Länge des gesamten Frames prüfen - frame_length = (data[0] & 0xFF) | ((data[1] & 0x07) << 8); + frame_length = EC_READ_U16(data) & 0x07FF; + data += EC_FRAME_HEADER_SIZE; if (unlikely(frame_length > received_length)) { printk(KERN_ERR "EtherCAT: Received corrupted frame (length does" @@ -381,10 +369,10 @@ int ec_frame_receive(ec_frame_t *frame /**< Gesendeter Rahmen */) } // Command header - data += EC_FRAME_HEADER_SIZE; - command_type = data[0]; - command_index = data[1]; - data_length = (data[6] & 0xFF) | ((data[7] & 0x07) << 8); + command_type = EC_READ_U8(data); + command_index = EC_READ_U8(data + 1); + data_length = EC_READ_U16(data + 6) & 0x07FF; + data += EC_COMMAND_HEADER_SIZE; if (unlikely(EC_FRAME_HEADER_SIZE + EC_COMMAND_HEADER_SIZE + data_length + EC_COMMAND_FOOTER_SIZE > received_length)) { @@ -399,7 +387,7 @@ int ec_frame_receive(ec_frame_t *frame /**< Gesendeter Rahmen */) || frame->data_length != data_length)) { printk(KERN_WARNING "EtherCAT: WARNING - Send/Receive anomaly!\n"); - ec_frame_print(frame); + ec_frame_print(frame); // FIXME uninteressant... ec_device_call_isr(device); // Empfangenes "vergessen" return -1; } @@ -407,12 +395,11 @@ int ec_frame_receive(ec_frame_t *frame /**< Gesendeter Rahmen */) frame->state = ec_frame_received; // Empfangene Daten in Kommandodatenspeicher kopieren - data += EC_COMMAND_HEADER_SIZE; memcpy(frame->data, data, data_length); data += data_length; // Working-Counter setzen - frame->working_counter = (data[0] & 0xFF) | ((data[1] & 0xFF) << 8); + frame->working_counter = EC_READ_U16(data); if (unlikely(frame->master->debug_level > 1)) { ec_frame_print(frame); diff --git a/master/frame.h b/master/frame.h index 133c4dc2..c0698d6f 100644 --- a/master/frame.h +++ b/master/frame.h @@ -68,13 +68,12 @@ typedef union { struct { - uint16_t slave; /**< Adresse des Slaves */ + uint16_t slave; /**< Adresse des Slaves (Ringposition oder Knoten) */ uint16_t mem; /**< Physikalische Speicheradresse im Slave */ } physical; /**< Physikalische Adresse */ uint32_t logical; /**< Logische Adresse */ - uint8_t raw[4]; /**< Rohdaten für die Generierung des Frames */ } ec_address_t; diff --git a/master/master.c b/master/master.c index 3d7c11e7..4ba06d51 100644 --- a/master/master.c +++ b/master/master.c @@ -15,6 +15,7 @@ #include <linux/delay.h> #include "../include/EtherCAT_rt.h" +#include "../include/EtherCAT_si.h" #include "globals.h" #include "master.h" #include "slave.h" @@ -201,11 +202,10 @@ int ec_scan_for_slaves(ec_master_t *master /**< EtherCAT-Master */) slave = master->slaves + i; // Write station address - data[0] = slave->station_address & 0x00FF; - data[1] = (slave->station_address & 0xFF00) >> 8; + EC_WRITE_U16(data, slave->station_address); - ec_frame_init_apwr(&frame, master, slave->ring_position, 0x0010, 2, - data); + ec_frame_init_apwr(&frame, master, slave->ring_position, 0x0010, + sizeof(uint16_t), data); if (unlikely(ec_frame_send_receive(&frame) < 0)) return -1; @@ -366,14 +366,11 @@ void ec_sync_config(const ec_sync_t *sync, /**< Sync-Manager */ uint8_t *data /**> Zeiger auf Konfigurationsspeicher */ ) { - data[0] = sync->physical_start_address & 0xFF; - data[1] = (sync->physical_start_address >> 8) & 0xFF; - data[2] = sync->size & 0xFF; - data[3] = (sync->size >> 8) & 0xFF; - data[4] = sync->control_byte; - data[5] = 0x00; - data[6] = 0x01; // enable - data[7] = 0x00; + EC_WRITE_U16(data, sync->physical_start_address); + EC_WRITE_U16(data + 2, sync->size); + EC_WRITE_U8 (data + 4, sync->control_byte); + EC_WRITE_U8 (data + 5, 0x00); // status byte (read only) + EC_WRITE_U16(data + 6, 0x0001); // enable } /*****************************************************************************/ @@ -389,22 +386,15 @@ void ec_fmmu_config(const ec_fmmu_t *fmmu, /**< Sync-Manager */ uint8_t *data /**> Zeiger auf Konfigurationsspeicher */ ) { - data[0] = fmmu->logical_start_address & 0xFF; - data[1] = (fmmu->logical_start_address >> 8) & 0xFF; - data[2] = (fmmu->logical_start_address >> 16) & 0xFF; - data[3] = (fmmu->logical_start_address >> 24) & 0xFF; - data[4] = fmmu->sync->size & 0xFF; - data[5] = (fmmu->sync->size >> 8) & 0xFF; - data[6] = 0x00; // Logical start bit - data[7] = 0x07; // Logical end bit - data[8] = fmmu->sync->physical_start_address & 0xFF; - data[9] = (fmmu->sync->physical_start_address >> 8) & 0xFF; - data[10] = 0x00; // Physical start bit - data[11] = (fmmu->sync->control_byte & 0x04) ? 0x02 : 0x01; - data[12] = 0x01; // Enable - data[13] = 0x00; // res. - data[14] = 0x00; // res. - data[15] = 0x00; // res. + EC_WRITE_U32(data, fmmu->logical_start_address); + EC_WRITE_U16(data + 4, fmmu->sync->size); + EC_WRITE_U8 (data + 6, 0x00); // Logical start bit + EC_WRITE_U8 (data + 7, 0x07); // Logical end bit + EC_WRITE_U16(data + 8, fmmu->sync->physical_start_address); + EC_WRITE_U8 (data + 10, 0x00); // Physical start bit + EC_WRITE_U8 (data + 11, (fmmu->sync->control_byte & 0x04) ? 0x02 : 0x01); + EC_WRITE_U16(data + 12, 0x0001); // Enable + EC_WRITE_U16(data + 14, 0x0000); // res. } /****************************************************************************** diff --git a/master/slave.c b/master/slave.c index 185e502f..f1bcbed0 100644 --- a/master/slave.c +++ b/master/slave.c @@ -11,6 +11,7 @@ #include <linux/module.h> #include <linux/delay.h> +#include "../include/EtherCAT_si.h" #include "globals.h" #include "slave.h" #include "frame.h" @@ -75,11 +76,11 @@ int ec_slave_fetch(ec_slave_t *slave /**< EtherCAT-Slave */) return -1; } - slave->base_type = frame.data[0]; - slave->base_revision = frame.data[1]; - slave->base_build = frame.data[2] | (frame.data[3] << 8); - slave->base_fmmu_count = frame.data[4]; - slave->base_sync_count = frame.data[5]; + slave->base_type = EC_READ_U8 (frame.data); + slave->base_revision = EC_READ_U8 (frame.data + 1); + slave->base_build = EC_READ_U16(frame.data + 2); + slave->base_fmmu_count = EC_READ_U8 (frame.data + 4); + slave->base_sync_count = EC_READ_U8 (frame.data + 5); if (slave->base_fmmu_count > EC_MAX_FMMUS) slave->base_fmmu_count = EC_MAX_FMMUS; @@ -135,12 +136,10 @@ int ec_slave_sii_read(ec_slave_t *slave, // Initiate read operation - data[0] = 0x00; - data[1] = 0x01; - data[2] = offset & 0xFF; - data[3] = (offset & 0xFF00) >> 8; - data[4] = 0x00; - data[5] = 0x00; + EC_WRITE_U8 (data, 0x00); + EC_WRITE_U8 (data + 1, 0x01); + EC_WRITE_U16(data + 2, offset); + EC_WRITE_U16(data + 4, 0x0000); ec_frame_init_npwr(&frame, slave->master, slave->station_address, 0x502, 6, data); @@ -173,7 +172,7 @@ int ec_slave_sii_read(ec_slave_t *slave, return -1; } - if (likely((frame.data[1] & 0x81) == 0)) { + if (likely((EC_READ_U8(frame.data + 1) & 0x81) == 0)) { memcpy(target, frame.data + 6, 4); break; } @@ -208,8 +207,7 @@ void ec_slave_state_ack(ec_slave_t *slave, unsigned char data[2]; unsigned int tries_left; - data[0] = state | EC_ACK; - data[1] = 0x00; + EC_WRITE_U16(data, state | EC_ACK); ec_frame_init_npwr(&frame, slave->master, slave->station_address, 0x0120, 2, data); @@ -247,14 +245,14 @@ void ec_slave_state_ack(ec_slave_t *slave, return; } - if (unlikely(frame.data[0] != state)) { + if (unlikely(EC_READ_U8(frame.data) != state)) { printk(KERN_ERR "EtherCAT: Could not acknowledge state %02X on" " slave %i (code %02X)!\n", state, slave->ring_position, - frame.data[0]); + EC_READ_U8(frame.data)); return; } - if (likely(frame.data[0] == state)) { + if (likely(EC_READ_U8(frame.data) == state)) { printk(KERN_INFO "EtherCAT: Acknowleged state %02X on slave %i.\n", state, slave->ring_position); return; @@ -289,8 +287,7 @@ int ec_slave_state_change(ec_slave_t *slave, unsigned char data[2]; unsigned int tries_left; - data[0] = state; - data[1] = 0x00; + EC_WRITE_U16(data, state); ec_frame_init_npwr(&frame, slave->master, slave->station_address, 0x0120, 2, data); @@ -327,15 +324,15 @@ int ec_slave_state_change(ec_slave_t *slave, return -1; } - if (unlikely(frame.data[0] & 0x10)) { // State change error + if (unlikely(EC_READ_U8(frame.data) & 0x10)) { // State change error printk(KERN_ERR "EtherCAT: Could not set state %02X - Slave %i" " refused state change (code %02X)!\n", state, - slave->ring_position, frame.data[0]); - ec_slave_state_ack(slave, frame.data[0] & 0x0F); + slave->ring_position, EC_READ_U8(frame.data)); + ec_slave_state_ack(slave, EC_READ_U8(frame.data) & 0x0F); return -1; } - if (likely(frame.data[0] == (state & 0x0F))) { + if (likely(EC_READ_U8(frame.data) == (state & 0x0F))) { // State change successful break; } @@ -442,7 +439,6 @@ int ec_slave_check_crc(ec_slave_t *slave /**< EtherCAT-Slave */) { ec_frame_t frame; uint8_t data[4]; - uint16_t crc[2]; ec_frame_init_nprd(&frame, slave->master, slave->station_address, 0x0300, 4); @@ -460,17 +456,16 @@ int ec_slave_check_crc(ec_slave_t *slave /**< EtherCAT-Slave */) return -1; } - crc[0] = frame.data[0] | (frame.data[1] << 8); - crc[1] = frame.data[2] | (frame.data[3] << 8); - // No CRC faults. - if (!crc[0] && !crc[1]) return 0; + if (!EC_READ_U16(frame.data) && !EC_READ_U16(frame.data + 2)) return 0; printk(KERN_INFO "EtherCAT: CRC faults on slave %i. A: %i, B: %i\n", - slave->ring_position, crc[0], crc[1]); + slave->ring_position, EC_READ_U16(frame.data), + EC_READ_U16(frame.data + 2)); // Reset CRC counters - memset(data, 0x00, 4); + EC_WRITE_U16(data, 0x0000); + EC_WRITE_U16(data + 2, 0x0000); ec_frame_init_npwr(&frame, slave->master, slave->station_address, 0x0300, 4, data); -- GitLab