47 |
47 |
48 /*****************************************************************************/ |
48 /*****************************************************************************/ |
49 |
49 |
50 /** |
50 /** |
51 Prepares a mailbox-send datagram. |
51 Prepares a mailbox-send datagram. |
52 \return pointer to mailbox datagram data |
52 \return Pointer to mailbox datagram data, or ERR_PTR() code. |
53 */ |
53 */ |
54 |
54 |
55 uint8_t *ec_slave_mbox_prepare_send(const ec_slave_t *slave, /**< slave */ |
55 uint8_t *ec_slave_mbox_prepare_send(const ec_slave_t *slave, /**< slave */ |
56 ec_datagram_t *datagram, /**< datagram */ |
56 ec_datagram_t *datagram, /**< datagram */ |
57 uint8_t type, /**< mailbox protocol */ |
57 uint8_t type, /**< mailbox protocol */ |
58 size_t size /**< size of the data */ |
58 size_t size /**< size of the data */ |
59 ) |
59 ) |
60 { |
60 { |
61 size_t total_size; |
61 size_t total_size; |
|
62 int ret; |
62 |
63 |
63 if (unlikely(!slave->sii.mailbox_protocols)) { |
64 if (unlikely(!slave->sii.mailbox_protocols)) { |
64 EC_ERR("Slave %u does not support mailbox communication!\n", |
65 EC_ERR("Slave %u does not support mailbox communication!\n", |
65 slave->ring_position); |
66 slave->ring_position); |
66 return NULL; |
67 return ERR_PTR(-EPROTONOSUPPORT); |
67 } |
68 } |
68 |
69 |
69 total_size = EC_MBOX_HEADER_SIZE + size; |
70 total_size = EC_MBOX_HEADER_SIZE + size; |
70 if (unlikely(total_size > slave->sii.rx_mailbox_size)) { |
71 if (unlikely(total_size > slave->sii.rx_mailbox_size)) { |
71 EC_ERR("Data size does not fit in mailbox!\n"); |
72 EC_ERR("Data size does not fit in mailbox!\n"); |
72 return NULL; |
73 return ERR_PTR(-EOVERFLOW); |
73 } |
74 } |
74 |
75 |
75 if (ec_datagram_fpwr(datagram, slave->station_address, |
76 ret = ec_datagram_fpwr(datagram, slave->station_address, |
76 slave->sii.rx_mailbox_offset, |
77 slave->sii.rx_mailbox_offset, |
77 slave->sii.rx_mailbox_size)) |
78 slave->sii.rx_mailbox_size); |
78 return NULL; |
79 if (ret) |
|
80 return ERR_PTR(ret); |
79 |
81 |
80 EC_WRITE_U16(datagram->data, size); // mailbox service data length |
82 EC_WRITE_U16(datagram->data, size); // mailbox service data length |
81 EC_WRITE_U16(datagram->data + 2, slave->station_address); // station addr. |
83 EC_WRITE_U16(datagram->data + 2, slave->station_address); // station addr. |
82 EC_WRITE_U8 (datagram->data + 4, 0x00); // channel & priority |
84 EC_WRITE_U8 (datagram->data + 4, 0x00); // channel & priority |
83 EC_WRITE_U8 (datagram->data + 5, type); // underlying protocol type |
85 EC_WRITE_U8 (datagram->data + 5, type); // underlying protocol type |
95 |
97 |
96 int ec_slave_mbox_prepare_check(const ec_slave_t *slave, /**< slave */ |
98 int ec_slave_mbox_prepare_check(const ec_slave_t *slave, /**< slave */ |
97 ec_datagram_t *datagram /**< datagram */ |
99 ec_datagram_t *datagram /**< datagram */ |
98 ) |
100 ) |
99 { |
101 { |
100 if (ec_datagram_fprd(datagram, slave->station_address, 0x808, 8)) |
102 int ret = ec_datagram_fprd(datagram, slave->station_address, 0x808, 8); |
101 return -1; |
103 if (ret) |
|
104 return ret; |
102 |
105 |
103 ec_datagram_zero(datagram); |
106 ec_datagram_zero(datagram); |
104 return 0; |
107 return 0; |
105 } |
108 } |
106 |
109 |
125 |
128 |
126 int ec_slave_mbox_prepare_fetch(const ec_slave_t *slave, /**< slave */ |
129 int ec_slave_mbox_prepare_fetch(const ec_slave_t *slave, /**< slave */ |
127 ec_datagram_t *datagram /**< datagram */ |
130 ec_datagram_t *datagram /**< datagram */ |
128 ) |
131 ) |
129 { |
132 { |
130 if (ec_datagram_fprd(datagram, slave->station_address, |
133 int ret = ec_datagram_fprd(datagram, slave->station_address, |
131 slave->sii.tx_mailbox_offset, |
134 slave->sii.tx_mailbox_offset, |
132 slave->sii.tx_mailbox_size)) |
135 slave->sii.tx_mailbox_size); |
133 return -1; |
136 if (ret) |
|
137 return ret; |
134 |
138 |
135 ec_datagram_zero(datagram); |
139 ec_datagram_zero(datagram); |
136 return 0; |
140 return 0; |
137 } |
141 } |
138 |
142 |
154 {} |
158 {} |
155 }; |
159 }; |
156 |
160 |
157 /*****************************************************************************/ |
161 /*****************************************************************************/ |
158 |
162 |
159 /** |
163 /** Processes received mailbox data. |
160 Processes received mailbox data. |
164 * |
161 \return pointer to the received data |
165 * \return Pointer to the received data, or ERR_PTR() code. |
162 */ |
166 */ |
163 |
|
164 uint8_t *ec_slave_mbox_fetch(const ec_slave_t *slave, /**< slave */ |
167 uint8_t *ec_slave_mbox_fetch(const ec_slave_t *slave, /**< slave */ |
165 ec_datagram_t *datagram, /**< datagram */ |
168 ec_datagram_t *datagram, /**< datagram */ |
166 uint8_t *type, /**< expected mailbox protocol */ |
169 uint8_t *type, /**< expected mailbox protocol */ |
167 size_t *size /**< size of the received data */ |
170 size_t *size /**< size of the received data */ |
168 ) |
171 ) |
173 |
176 |
174 if (data_size + EC_MBOX_HEADER_SIZE > slave->sii.tx_mailbox_size) { |
177 if (data_size + EC_MBOX_HEADER_SIZE > slave->sii.tx_mailbox_size) { |
175 EC_ERR("Corrupt mailbox response received from slave %u!\n", |
178 EC_ERR("Corrupt mailbox response received from slave %u!\n", |
176 slave->ring_position); |
179 slave->ring_position); |
177 ec_print_data(datagram->data, slave->sii.tx_mailbox_size); |
180 ec_print_data(datagram->data, slave->sii.tx_mailbox_size); |
178 return NULL; |
181 return ERR_PTR(-EPROTO); |
179 } |
182 } |
180 |
183 |
181 *type = EC_READ_U8(datagram->data + 5) & 0x0F; |
184 *type = EC_READ_U8(datagram->data + 5) & 0x0F; |
182 *size = data_size; |
185 *size = data_size; |
183 |
186 |