IgH EtherCAT Master  1.6.9
mailbox.c
Go to the documentation of this file.
1/*****************************************************************************
2 *
3 * Copyright (C) 2006-2008 Florian Pose, Ingenieurgemeinschaft IgH
4 *
5 * This file is part of the IgH EtherCAT Master.
6 *
7 * The IgH EtherCAT Master is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License version 2, as
9 * published by the Free Software Foundation.
10 *
11 * The IgH EtherCAT Master is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
14 * Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with the IgH EtherCAT Master; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 *
20 ****************************************************************************/
21
26
27/****************************************************************************/
28
29#include <linux/slab.h>
30#include <linux/delay.h>
31
32#include "mailbox.h"
33#include "datagram.h"
34#include "master.h"
35
36/****************************************************************************/
37
42
44 ec_datagram_t *datagram,
45 uint8_t type,
46 size_t size
47 )
48{
49 size_t total_size;
50 int ret;
51
52 if (unlikely(!slave->sii.mailbox_protocols)) {
53 EC_SLAVE_ERR(slave, "Slave does not support mailbox"
54 " communication!\n");
55 return ERR_PTR(-EPROTONOSUPPORT);
56 }
57
58 total_size = EC_MBOX_HEADER_SIZE + size;
59
60 if (unlikely(total_size > slave->configured_rx_mailbox_size)) {
61 EC_SLAVE_ERR(slave, "Data size (%zu) does not fit in mailbox (%u)!\n",
62 total_size, slave->configured_rx_mailbox_size);
63 return ERR_PTR(-ENOBUFS);
64 }
65
66 ret = ec_datagram_fpwr(datagram, slave->station_address,
69 if (ret)
70 return ERR_PTR(ret);
71
72 EC_WRITE_U16(datagram->data, size); // mailbox service data length
73 EC_WRITE_U16(datagram->data + 2, slave->station_address); // station addr.
74 EC_WRITE_U8 (datagram->data + 4, 0x00); // channel & priority
75 EC_WRITE_U8 (datagram->data + 5, type); // underlying protocol type
76
77 return datagram->data + EC_MBOX_HEADER_SIZE;
78}
79
80/****************************************************************************/
81
87
89 ec_datagram_t *datagram
90 )
91{
92 int ret = ec_datagram_fprd(datagram, slave->station_address, 0x808, 8);
93 if (ret)
94 return ret;
95
96 ec_datagram_zero(datagram);
97 return 0;
98}
99
100/****************************************************************************/
101
106
108{
109 return EC_READ_U8(datagram->data + 5) & 8 ? 1 : 0;
110}
111
112/****************************************************************************/
113
118
120 ec_datagram_t *datagram
121 )
122{
123 int ret = ec_datagram_fprd(datagram, slave->station_address,
126 if (ret)
127 return ret;
128
129 ec_datagram_zero(datagram);
130 return 0;
131}
132
133/****************************************************************************/
134
138
140 {0x00000001, "MBXERR_SYNTAX"},
141 {0x00000002, "MBXERR_UNSUPPORTEDPROTOCOL"},
142 {0x00000003, "MBXERR_INVAILDCHANNEL"},
143 {0x00000004, "MBXERR_SERVICENOTSUPPORTED"},
144 {0x00000005, "MBXERR_INVALIDHEADER"},
145 {0x00000006, "MBXERR_SIZETOOSHORT"},
146 {0x00000007, "MBXERR_NOMOREMEMORY"},
147 {0x00000008, "MBXERR_INVALIDSIZE"},
148 {}
149};
150
151/****************************************************************************/
152
157uint8_t *ec_slave_mbox_fetch(const ec_slave_t *slave,
158 const ec_datagram_t *datagram,
159 uint8_t *type,
160 size_t *size
161 )
162{
163 size_t data_size;
164
165 data_size = EC_READ_U16(datagram->data);
166
167 if (data_size + EC_MBOX_HEADER_SIZE > slave->configured_tx_mailbox_size) {
168 EC_SLAVE_ERR(slave, "Corrupt mailbox response received!\n");
170 return ERR_PTR(-EPROTO);
171 }
172
173 *type = EC_READ_U8(datagram->data + 5) & 0x0F;
174 *size = data_size;
175
176 if (*type == 0x00) {
177 const ec_code_msg_t *mbox_msg;
178 uint16_t code = EC_READ_U16(datagram->data + 8);
179
180 EC_SLAVE_ERR(slave, "Mailbox error response received - ");
181
182 for (mbox_msg = mbox_error_messages; mbox_msg->code; mbox_msg++) {
183 if (mbox_msg->code != code)
184 continue;
185 printk(KERN_CONT "Code 0x%04X: \"%s\".\n",
186 mbox_msg->code, mbox_msg->message);
187 break;
188 }
189
190 if (!mbox_msg->code) {
191 printk(KERN_CONT "Unknown error reply code 0x%04X.\n", code);
192 }
193
194 if (slave->master->debug_level)
195 ec_print_data(datagram->data + EC_MBOX_HEADER_SIZE, data_size);
196
197 return ERR_PTR(-EPROTO);
198 }
199
200 return datagram->data + EC_MBOX_HEADER_SIZE;
201}
202
203/****************************************************************************/
void ec_datagram_zero(ec_datagram_t *datagram)
Fills the datagram payload memory with zeros.
Definition datagram.c:170
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:290
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:265
EtherCAT datagram structure.
#define EC_MBOX_HEADER_SIZE
Mailbox header size.
Definition globals.h:83
struct ec_slave ec_slave_t
Definition globals.h:310
void ec_print_data(const uint8_t *, size_t)
Outputs frame contents for debugging purposes.
Definition module.c:344
#define EC_WRITE_U8(DATA, VAL)
Write an 8-bit unsigned value to EtherCAT data.
Definition ecrt.h:3040
#define EC_READ_U16(DATA)
Read a 16-bit unsigned value from EtherCAT data.
Definition ecrt.h:2948
#define EC_READ_U8(DATA)
Read an 8-bit unsigned value from EtherCAT data.
Definition ecrt.h:2932
#define EC_WRITE_U16(DATA, VAL)
Write a 16-bit unsigned value to EtherCAT data.
Definition ecrt.h:3057
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:157
const ec_code_msg_t mbox_error_messages[]
Mailbox error codes.
Definition mailbox.c:139
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:88
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:119
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:43
int ec_slave_mbox_check(const ec_datagram_t *datagram)
Processes a mailbox state checking datagram.
Definition mailbox.c:107
Mailbox functionality.
EtherCAT master structure.
#define EC_SLAVE_ERR(slave, fmt, args...)
Convenience macro for printing slave-specific errors to syslog.
Definition slave.h:68
Code/Message pair.
Definition globals.h:275
uint32_t code
Code.
Definition globals.h:276
const char * message
Message belonging to code.
Definition globals.h:277
EtherCAT datagram.
Definition datagram.h:79
uint8_t * data
Datagram payload.
Definition datagram.h:88
unsigned int debug_level
Master debug level.
Definition master.h:275
uint16_t mailbox_protocols
Supported mailbox protocols.
Definition slave.h:139
uint16_t configured_rx_mailbox_size
Configured receive mailbox size.
Definition slave.h:189
ec_sii_t sii
Extracted SII data.
Definition slave.h:215
uint16_t configured_tx_mailbox_offset
Configured send mailbox offset.
Definition slave.h:191
uint16_t configured_tx_mailbox_size
Configured send mailbox size.
Definition slave.h:193
uint16_t configured_rx_mailbox_offset
Configured receive mailbox offset.
Definition slave.h:187
ec_master_t * master
Master owning the slave.
Definition slave.h:170
uint16_t station_address
Configured station address.
Definition slave.h:176