Main Page | Modules | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

mailbox.c

Go to the documentation of this file.
00001 /******************************************************************************
00002  *
00003  *  $Id: mailbox.c 682 2006-11-07 12:13:30Z fp $
00004  *
00005  *  Copyright (C) 2006  Florian Pose, Ingenieurgemeinschaft IgH
00006  *
00007  *  This file is part of the IgH EtherCAT Master.
00008  *
00009  *  The IgH EtherCAT Master is free software; you can redistribute it
00010  *  and/or modify it under the terms of the GNU General Public License
00011  *  as published by the Free Software Foundation; either version 2 of the
00012  *  License, or (at your option) any later version.
00013  *
00014  *  The IgH EtherCAT Master is distributed in the hope that it will be
00015  *  useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  *  GNU General Public License for more details.
00018  *
00019  *  You should have received a copy of the GNU General Public License
00020  *  along with the IgH EtherCAT Master; if not, write to the Free Software
00021  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00022  *
00023  *  The right to use EtherCAT Technology is granted and comes free of
00024  *  charge under condition of compatibility of product made by
00025  *  Licensee. People intending to distribute/sell products based on the
00026  *  code, have to sign an agreement to guarantee that products using
00027  *  software based on IgH EtherCAT master stay compatible with the actual
00028  *  EtherCAT specification (which are released themselves as an open
00029  *  standard) as the (only) precondition to have the right to use EtherCAT
00030  *  Technology, IP and trade marks.
00031  *
00032  *****************************************************************************/
00033 
00039 /*****************************************************************************/
00040 
00041 #include <linux/slab.h>
00042 #include <linux/delay.h>
00043 
00044 #include "mailbox.h"
00045 #include "datagram.h"
00046 #include "master.h"
00047 
00048 /*****************************************************************************/
00049 
00055 uint8_t *ec_slave_mbox_prepare_send(const ec_slave_t *slave, 
00056                                     ec_datagram_t *datagram, 
00057                                     uint8_t type, 
00058                                     size_t size 
00059                                     )
00060 {
00061     size_t total_size;
00062 
00063     if (unlikely(!slave->sii_mailbox_protocols)) {
00064         EC_ERR("Slave %i does not support mailbox communication!\n",
00065                slave->ring_position);
00066         return NULL;
00067     }
00068 
00069     total_size = size + 6;
00070     if (unlikely(total_size > slave->sii_rx_mailbox_size)) {
00071         EC_ERR("Data size does not fit in mailbox!\n");
00072         return NULL;
00073     }
00074 
00075     if (ec_datagram_npwr(datagram, slave->station_address,
00076                          slave->sii_rx_mailbox_offset,
00077                          slave->sii_rx_mailbox_size))
00078         return NULL;
00079 
00080     EC_WRITE_U16(datagram->data,     size); // mailbox service data length
00081     EC_WRITE_U16(datagram->data + 2, slave->station_address); // station addr.
00082     EC_WRITE_U8 (datagram->data + 4, 0x00); // channel & priority
00083     EC_WRITE_U8 (datagram->data + 5, type); // underlying protocol type
00084 
00085     return datagram->data + 6;
00086 }
00087 
00088 /*****************************************************************************/
00089 
00095 int ec_slave_mbox_prepare_check(const ec_slave_t *slave, 
00096                                 ec_datagram_t *datagram 
00097                                 )
00098 {
00099     // FIXME: second sync manager?
00100     if (ec_datagram_nprd(datagram, slave->station_address, 0x808, 8))
00101         return -1;
00102 
00103     return 0;
00104 }
00105 
00106 /*****************************************************************************/
00107 
00113 int ec_slave_mbox_check(const ec_datagram_t *datagram )
00114 {
00115     return EC_READ_U8(datagram->data + 5) & 8 ? 1 : 0;
00116 }
00117 
00118 /*****************************************************************************/
00119 
00125 int ec_slave_mbox_prepare_fetch(const ec_slave_t *slave, 
00126                                 ec_datagram_t *datagram 
00127                                 )
00128 {
00129     if (ec_datagram_nprd(datagram, slave->station_address,
00130                          slave->sii_tx_mailbox_offset,
00131                          slave->sii_tx_mailbox_size)) return -1;
00132     return 0;
00133 }
00134 
00135 /*****************************************************************************/
00136 
00141 const ec_code_msg_t mbox_error_messages[] = {
00142     {0x00000001, "MBXERR_SYNTAX"},
00143     {0x00000002, "MBXERR_UNSUPPORTEDPROTOCOL"},
00144     {0x00000003, "MBXERR_INVAILDCHANNEL"},
00145     {0x00000004, "MBXERR_SERVICENOTSUPPORTED"},
00146     {0x00000005, "MBXERR_INVALIDHEADER"},
00147     {0x00000006, "MBXERR_SIZETOOSHORT"},
00148     {0x00000007, "MBXERR_NOMOREMEMORY"},
00149     {0x00000008, "MBXERR_INVALIDSIZE"},
00150     {}
00151 };
00152 
00153 /*****************************************************************************/
00154 
00160 uint8_t *ec_slave_mbox_fetch(const ec_slave_t *slave, 
00161                              ec_datagram_t *datagram, 
00162                              uint8_t *type, 
00163                              size_t *size 
00164                              )
00165 {
00166     size_t data_size;
00167 
00168     data_size = EC_READ_U16(datagram->data);
00169 
00170     if (data_size > slave->sii_tx_mailbox_size - 6) {
00171         EC_ERR("Corrupt mailbox response detected!\n");
00172         ec_print_data(datagram->data, slave->sii_tx_mailbox_size);
00173         return NULL;
00174     }
00175 
00176     *type = EC_READ_U8(datagram->data + 5) & 0x0F;
00177     *size = data_size;
00178 
00179     if (*type == 0x00) {
00180         const ec_code_msg_t *mbox_msg;
00181     uint16_t code = EC_READ_U16(datagram->data + 8);
00182 
00183         EC_ERR("Mailbox error response received - ");
00184 
00185     for (mbox_msg = mbox_error_messages; mbox_msg->code; mbox_msg++) {
00186             if (mbox_msg->code != code) continue;
00187             printk("Code 0x%04X: \"%s\".\n",
00188                    mbox_msg->code, mbox_msg->message);
00189             break;
00190         }
00191 
00192         if (!mbox_msg->code)
00193             printk("Unknown error reply code 0x%04X.\n", code);
00194 
00195         if (slave->master->debug_level)
00196             ec_print_data(datagram->data + 6, data_size);
00197 
00198         return NULL;
00199     }
00200 
00201     return datagram->data + 6;
00202 }
00203 
00204 /*****************************************************************************/

Generated on Tue Nov 7 15:03:36 2006 for IgH EtherCAT master by  doxygen 1.4.4