00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
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);
00081 EC_WRITE_U16(datagram->data + 2, slave->station_address);
00082 EC_WRITE_U8 (datagram->data + 4, 0x00);
00083 EC_WRITE_U8 (datagram->data + 5, 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
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