IgH EtherCAT Master  1.5.3
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 
51 uint8_t *ec_slave_mbox_prepare_send(const ec_slave_t *slave,
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 
115 int ec_slave_mbox_check(const ec_datagram_t *datagram )
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 
165 uint8_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");
177  ec_print_data(datagram->data, slave->configured_tx_mailbox_size);
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 /*****************************************************************************/
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
ec_sii_t sii
Extracted SII data.
Definition: slave.h:223
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
uint16_t configured_tx_mailbox_size
Configured send mailbox size.
Definition: slave.h:201
uint16_t configured_tx_mailbox_offset
Configured send mailbox offset.
Definition: slave.h:199
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
uint32_t code
Code.
Definition: globals.h:267
EtherCAT datagram.
Definition: datagram.h:87
#define EC_WRITE_U8(DATA, VAL)
Write an 8-bit unsigned value to EtherCAT data.
Definition: ecrt.h:2401
uint16_t station_address
Configured station address.
Definition: slave.h:184
const char * message
Message belonging to code.
Definition: globals.h:268
EtherCAT master structure.
EtherCAT slave.
Definition: slave.h:176
void ec_datagram_zero(ec_datagram_t *datagram)
Fills the datagram payload memory with zeros.
Definition: datagram.c:178
Code/Message pair.
Definition: globals.h:266
uint16_t mailbox_protocols
Supported mailbox protocols.
Definition: slave.h:147
unsigned int debug_level
Master debug level.
Definition: master.h:285
#define EC_SLAVE_ERR(slave, fmt, args...)
Convenience macro for printing slave-specific errors to syslog.
Definition: slave.h:76
#define EC_WRITE_U16(DATA, VAL)
Write a 16-bit unsigned value to EtherCAT data.
Definition: ecrt.h:2418
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
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.
const ec_code_msg_t mbox_error_messages[]
Mailbox error codes.
Definition: mailbox.c:147
#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
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
#define EC_READ_U16(DATA)
Read a 16-bit unsigned value from EtherCAT data.
Definition: ecrt.h:2313
Mailbox functionality.
uint16_t configured_rx_mailbox_size
Configured receive mailbox size.
Definition: slave.h:197
uint8_t * data
Datagram payload.
Definition: datagram.h:94
#define EC_READ_U8(DATA)
Read an 8-bit unsigned value from EtherCAT data.
Definition: ecrt.h:2297
int ec_slave_mbox_check(const ec_datagram_t *datagram)
Processes a mailbox state checking datagram.
Definition: mailbox.c:115