IgH EtherCAT Master  1.5.2
mailbox.c
Go to the documentation of this file.
1/******************************************************************************
2 *
3 * $Id$
4 *
5 * Copyright (C) 2006-2008 Florian Pose, Ingenieurgemeinschaft IgH
6 *
7 * This file is part of the IgH EtherCAT Master.
8 *
9 * The IgH EtherCAT Master is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License version 2, as
11 * published by the Free Software Foundation.
12 *
13 * The IgH EtherCAT Master is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
16 * Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with the IgH EtherCAT Master; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 *
22 * ---
23 *
24 * The license mentioned above concerns the source code only. Using the
25 * EtherCAT technology and brand is only permitted in compliance with the
26 * industrial property and similar rights of Beckhoff Automation GmbH.
27 *
28 *****************************************************************************/
29
35/*****************************************************************************/
36
37#include <linux/slab.h>
38#include <linux/delay.h>
39
40#include "mailbox.h"
41#include "datagram.h"
42#include "master.h"
43
44/*****************************************************************************/
45
52 ec_datagram_t *datagram,
53 uint8_t type,
54 size_t size
55 )
56{
57 size_t total_size;
58 int ret;
59
60 if (unlikely(!slave->sii.mailbox_protocols)) {
61 EC_SLAVE_ERR(slave, "Slave does not support mailbox"
62 " communication!\n");
63 return ERR_PTR(-EPROTONOSUPPORT);
64 }
65
66 total_size = EC_MBOX_HEADER_SIZE + size;
67
68 if (unlikely(total_size > slave->configured_rx_mailbox_size)) {
69 EC_SLAVE_ERR(slave, "Data size (%zu) does not fit in mailbox (%u)!\n",
70 total_size, slave->configured_rx_mailbox_size);
71 return ERR_PTR(-EOVERFLOW);
72 }
73
74 ret = ec_datagram_fpwr(datagram, slave->station_address,
77 if (ret)
78 return ERR_PTR(ret);
79
80 EC_WRITE_U16(datagram->data, size); // mailbox service data length
81 EC_WRITE_U16(datagram->data + 2, slave->station_address); // station addr.
82 EC_WRITE_U8 (datagram->data + 4, 0x00); // channel & priority
83 EC_WRITE_U8 (datagram->data + 5, type); // underlying protocol type
84
85 return datagram->data + EC_MBOX_HEADER_SIZE;
86}
87
88/*****************************************************************************/
89
97 ec_datagram_t *datagram
98 )
99{
100 int ret = ec_datagram_fprd(datagram, slave->station_address, 0x808, 8);
101 if (ret)
102 return ret;
103
104 ec_datagram_zero(datagram);
105 return 0;
106}
107
108/*****************************************************************************/
109
116{
117 return EC_READ_U8(datagram->data + 5) & 8 ? 1 : 0;
118}
119
120/*****************************************************************************/
121
128 ec_datagram_t *datagram
129 )
130{
131 int ret = ec_datagram_fprd(datagram, slave->station_address,
134 if (ret)
135 return ret;
136
137 ec_datagram_zero(datagram);
138 return 0;
139}
140
141/*****************************************************************************/
142
148 {0x00000001, "MBXERR_SYNTAX"},
149 {0x00000002, "MBXERR_UNSUPPORTEDPROTOCOL"},
150 {0x00000003, "MBXERR_INVAILDCHANNEL"},
151 {0x00000004, "MBXERR_SERVICENOTSUPPORTED"},
152 {0x00000005, "MBXERR_INVALIDHEADER"},
153 {0x00000006, "MBXERR_SIZETOOSHORT"},
154 {0x00000007, "MBXERR_NOMOREMEMORY"},
155 {0x00000008, "MBXERR_INVALIDSIZE"},
156 {}
157};
158
159/*****************************************************************************/
160
165uint8_t *ec_slave_mbox_fetch(const ec_slave_t *slave,
166 const ec_datagram_t *datagram,
167 uint8_t *type,
168 size_t *size
169 )
170{
171 size_t data_size;
172
173 data_size = EC_READ_U16(datagram->data);
174
175 if (data_size + EC_MBOX_HEADER_SIZE > slave->configured_tx_mailbox_size) {
176 EC_SLAVE_ERR(slave, "Corrupt mailbox response received!\n");
178 return ERR_PTR(-EPROTO);
179 }
180
181 *type = EC_READ_U8(datagram->data + 5) & 0x0F;
182 *size = data_size;
183
184 if (*type == 0x00) {
185 const ec_code_msg_t *mbox_msg;
186 uint16_t code = EC_READ_U16(datagram->data + 8);
187
188 EC_SLAVE_ERR(slave, "Mailbox error response received - ");
189
190 for (mbox_msg = mbox_error_messages; mbox_msg->code; mbox_msg++) {
191 if (mbox_msg->code != code)
192 continue;
193 printk(KERN_CONT "Code 0x%04X: \"%s\".\n",
194 mbox_msg->code, mbox_msg->message);
195 break;
196 }
197
198 if (!mbox_msg->code) {
199 printk(KERN_CONT "Unknown error reply code 0x%04X.\n", code);
200 }
201
202 if (slave->master->debug_level)
203 ec_print_data(datagram->data + EC_MBOX_HEADER_SIZE, data_size);
204
205 return ERR_PTR(-EPROTO);
206 }
207
208 return datagram->data + EC_MBOX_HEADER_SIZE;
209}
210
211/*****************************************************************************/
void ec_datagram_zero(ec_datagram_t *datagram)
Fills the datagram payload memory with zeros.
Definition: datagram.c:178
int ec_datagram_fpwr(ec_datagram_t *datagram, uint16_t configured_address, uint16_t mem_address, size_t data_size)
Initializes an EtherCAT FPWR datagram.
Definition: datagram.c:298
int ec_datagram_fprd(ec_datagram_t *datagram, uint16_t configured_address, uint16_t mem_address, size_t data_size)
Initializes an EtherCAT FPRD datagram.
Definition: datagram.c:273
EtherCAT datagram structure.
#define EC_MBOX_HEADER_SIZE
Mailbox header size.
Definition: globals.h:83
void ec_print_data(const uint8_t *, size_t)
Outputs frame contents for debugging purposes.
Definition: module.c:348
#define EC_WRITE_U8(DATA, VAL)
Write an 8-bit unsigned value to EtherCAT data.
Definition: ecrt.h:2266
#define EC_READ_U16(DATA)
Read a 16-bit unsigned value from EtherCAT data.
Definition: ecrt.h:2178
#define EC_READ_U8(DATA)
Read an 8-bit unsigned value from EtherCAT data.
Definition: ecrt.h:2162
#define EC_WRITE_U16(DATA, VAL)
Write a 16-bit unsigned value to EtherCAT data.
Definition: ecrt.h:2283
uint8_t * ec_slave_mbox_fetch(const ec_slave_t *slave, const ec_datagram_t *datagram, uint8_t *type, size_t *size)
Processes received mailbox data.
Definition: mailbox.c:165
const ec_code_msg_t mbox_error_messages[]
Mailbox error codes.
Definition: mailbox.c:147
int ec_slave_mbox_prepare_check(const ec_slave_t *slave, ec_datagram_t *datagram)
Prepares a datagram for checking the mailbox state.
Definition: mailbox.c:96
int ec_slave_mbox_prepare_fetch(const ec_slave_t *slave, ec_datagram_t *datagram)
Prepares a datagram to fetch mailbox data.
Definition: mailbox.c:127
uint8_t * ec_slave_mbox_prepare_send(const ec_slave_t *slave, ec_datagram_t *datagram, uint8_t type, size_t size)
Prepares a mailbox-send datagram.
Definition: mailbox.c:51
int ec_slave_mbox_check(const ec_datagram_t *datagram)
Processes a mailbox state checking datagram.
Definition: mailbox.c:115
Mailbox functionality.
EtherCAT master structure.
#define EC_SLAVE_ERR(slave, fmt, args...)
Convenience macro for printing slave-specific errors to syslog.
Definition: slave.h:76
Code/Message pair.
Definition: globals.h:266
uint32_t code
Code.
Definition: globals.h:267
const char * message
Message belonging to code.
Definition: globals.h:268
EtherCAT datagram.
Definition: datagram.h:87
uint8_t * data
Datagram payload.
Definition: datagram.h:94
unsigned int debug_level
Master debug level.
Definition: master.h:285
uint16_t mailbox_protocols
Supported mailbox protocols.
Definition: slave.h:147
EtherCAT slave.
Definition: slave.h:177
uint16_t configured_rx_mailbox_size
Configured receive mailbox size.
Definition: slave.h:197
ec_sii_t sii
Extracted SII data.
Definition: slave.h:223
uint16_t configured_tx_mailbox_offset
Configured send mailbox offset.
Definition: slave.h:199
uint16_t configured_tx_mailbox_size
Configured send mailbox size.
Definition: slave.h:201
uint16_t configured_rx_mailbox_offset
Configured receive mailbox offset.
Definition: slave.h:195
ec_master_t * master
Master owning the slave.
Definition: slave.h:178
uint16_t station_address
Configured station address.
Definition: slave.h:184