223 data fields. |
223 data fields. |
224 \return 0 in case of success, else < 0 |
224 \return 0 in case of success, else < 0 |
225 */ |
225 */ |
226 |
226 |
227 int ec_domain_alloc(ec_domain_t *domain, /**< EtherCAT domain */ |
227 int ec_domain_alloc(ec_domain_t *domain, /**< EtherCAT domain */ |
228 uint32_t base_address /**< Logische Basisadresse */ |
228 uint32_t base_address /**< logical base address */ |
229 ) |
229 ) |
230 { |
230 { |
231 ec_field_reg_t *field_reg; |
231 ec_field_reg_t *field_reg; |
232 ec_slave_t *slave; |
232 ec_slave_t *slave; |
233 ec_fmmu_t *fmmu; |
233 ec_fmmu_t *fmmu; |
234 unsigned int i, j, cmd_count; |
234 unsigned int i, j, cmd_count; |
235 uint32_t field_off, field_off_cmd; |
235 uint32_t field_off, field_off_cmd; |
236 uint32_t cmd_offset; |
236 uint32_t cmd_offset; |
237 size_t cmd_data_size; |
237 size_t cmd_data_size, sync_size; |
238 ec_command_t *command; |
238 ec_command_t *command; |
239 |
239 |
240 domain->base_address = base_address; |
240 domain->base_address = base_address; |
241 |
241 |
242 // Größe der Prozessdaten berechnen und Kommandos allozieren |
242 // calculate size of process data and allocate memory |
243 domain->data_size = 0; |
243 domain->data_size = 0; |
244 cmd_offset = base_address; |
244 cmd_offset = base_address; |
245 cmd_data_size = 0; |
245 cmd_data_size = 0; |
246 cmd_count = 0; |
246 cmd_count = 0; |
247 list_for_each_entry(slave, &domain->master->slaves, list) { |
247 list_for_each_entry(slave, &domain->master->slaves, list) { |
248 for (j = 0; j < slave->fmmu_count; j++) { |
248 for (j = 0; j < slave->fmmu_count; j++) { |
249 fmmu = &slave->fmmus[j]; |
249 fmmu = &slave->fmmus[j]; |
250 if (fmmu->domain == domain) { |
250 if (fmmu->domain == domain) { |
251 fmmu->logical_start_address = base_address + domain->data_size; |
251 fmmu->logical_start_address = base_address + domain->data_size; |
252 domain->data_size += fmmu->sync->size; |
252 sync_size = ec_slave_calc_sync_size(slave, fmmu->sync); |
253 if (cmd_data_size + fmmu->sync->size > EC_MAX_DATA_SIZE) { |
253 domain->data_size += sync_size; |
|
254 if (cmd_data_size + sync_size > EC_MAX_DATA_SIZE) { |
254 if (ec_domain_add_command(domain, cmd_offset, |
255 if (ec_domain_add_command(domain, cmd_offset, |
255 cmd_data_size)) return -1; |
256 cmd_data_size)) return -1; |
256 cmd_offset += cmd_data_size; |
257 cmd_offset += cmd_data_size; |
257 cmd_data_size = 0; |
258 cmd_data_size = 0; |
258 cmd_count++; |
259 cmd_count++; |
259 } |
260 } |
260 cmd_data_size += fmmu->sync->size; |
261 cmd_data_size += sync_size; |
261 } |
262 } |
262 } |
263 } |
263 } |
264 } |
264 |
265 |
265 // Letztes Kommando allozieren |
266 // allocate last command |
266 if (cmd_data_size) { |
267 if (cmd_data_size) { |
267 if (ec_domain_add_command(domain, cmd_offset, cmd_data_size)) |
268 if (ec_domain_add_command(domain, cmd_offset, cmd_data_size)) |
268 return -1; |
269 return -1; |
269 cmd_count++; |
270 cmd_count++; |
270 } |
271 } |
273 EC_WARN("Domain %i contains no data!\n", domain->index); |
274 EC_WARN("Domain %i contains no data!\n", domain->index); |
274 ec_domain_clear_field_regs(domain); |
275 ec_domain_clear_field_regs(domain); |
275 return 0; |
276 return 0; |
276 } |
277 } |
277 |
278 |
278 // Alle Prozessdatenzeiger setzen |
279 // set all process data pointers |
279 list_for_each_entry(field_reg, &domain->field_regs, list) { |
280 list_for_each_entry(field_reg, &domain->field_regs, list) { |
280 for (i = 0; i < field_reg->slave->fmmu_count; i++) { |
281 for (i = 0; i < field_reg->slave->fmmu_count; i++) { |
281 fmmu = &field_reg->slave->fmmus[i]; |
282 fmmu = &field_reg->slave->fmmus[i]; |
282 if (fmmu->domain == domain && fmmu->sync == field_reg->sync) { |
283 if (fmmu->domain == domain && fmmu->sync == field_reg->sync) { |
283 field_off = fmmu->logical_start_address + |
284 field_off = fmmu->logical_start_address + |
284 field_reg->field_offset; |
285 field_reg->field_offset; |
285 // Kommando suchen |
286 // search command |
286 list_for_each_entry(command, &domain->commands, list) { |
287 list_for_each_entry(command, &domain->commands, list) { |
287 field_off_cmd = field_off - command->address.logical; |
288 field_off_cmd = field_off - command->address.logical; |
288 if (field_off >= command->address.logical && |
289 if (field_off >= command->address.logical && |
289 field_off_cmd < command->mem_size) { |
290 field_off_cmd < command->mem_size) { |
290 *field_reg->data_ptr = command->data + field_off_cmd; |
291 *field_reg->data_ptr = command->data + field_off_cmd; |