159 uint8_t sync_index, /**< Sync manager index. */ |
159 uint8_t sync_index, /**< Sync manager index. */ |
160 ec_direction_t dir /**< PDO direction. */ |
160 ec_direction_t dir /**< PDO direction. */ |
161 ) |
161 ) |
162 { |
162 { |
163 unsigned int i; |
163 unsigned int i; |
164 ec_fmmu_config_t *fmmu; |
164 ec_fmmu_config_t *fmmu, *prev_fmmu; |
165 ec_fmmu_config_t *prev_fmmu; |
|
166 uint32_t fmmu_logical_start_address; |
165 uint32_t fmmu_logical_start_address; |
167 size_t tx_size, old_prev_tx_size; |
166 size_t tx_size, old_prev_tx_size; |
168 |
167 |
169 // FMMU configuration already prepared? |
168 // FMMU configuration already prepared? |
170 for (i = 0; i < sc->used_fmmus; i++) { |
169 for (i = 0; i < sc->used_fmmus; i++) { |
182 |
181 |
183 ec_mutex_lock(&sc->master->master_mutex); |
182 ec_mutex_lock(&sc->master->master_mutex); |
184 ec_fmmu_config_init(fmmu, sc, sync_index, dir); |
183 ec_fmmu_config_init(fmmu, sc, sync_index, dir); |
185 fmmu_logical_start_address = domain->tx_size; |
184 fmmu_logical_start_address = domain->tx_size; |
186 tx_size = fmmu->data_size; |
185 tx_size = fmmu->data_size; |
|
186 |
|
187 // FIXME is it enough to take only the *previous* FMMU into account? |
|
188 |
187 if (sc->allow_overlapping_pdos && sc->used_fmmus > 0) { |
189 if (sc->allow_overlapping_pdos && sc->used_fmmus > 0) { |
188 prev_fmmu = &sc->fmmu_configs[sc->used_fmmus-1]; |
190 prev_fmmu = &sc->fmmu_configs[sc->used_fmmus - 1]; |
189 if (fmmu->dir != prev_fmmu->dir && prev_fmmu->tx_size != 0) { |
191 if (fmmu->dir != prev_fmmu->dir && prev_fmmu->tx_size != 0) { |
190 // prev fmmu has opposite direction |
192 // prev fmmu has opposite direction |
191 // and is not already paired with prev-prev fmmu |
193 // and is not already paired with prev-prev fmmu |
192 old_prev_tx_size = prev_fmmu->tx_size; |
194 old_prev_tx_size = prev_fmmu->tx_size; |
193 prev_fmmu->tx_size = max(fmmu->data_size,prev_fmmu->data_size); |
195 prev_fmmu->tx_size = max(fmmu->data_size, prev_fmmu->data_size); |
194 domain->tx_size += prev_fmmu->tx_size - old_prev_tx_size; |
196 domain->tx_size += prev_fmmu->tx_size - old_prev_tx_size; |
195 tx_size = 0; |
197 tx_size = 0; |
196 fmmu_logical_start_address = prev_fmmu->logical_start_address; |
198 fmmu_logical_start_address = prev_fmmu->logical_start_address; |
197 } |
199 } |
198 } |
200 } |
199 ec_fmmu_config_domain(fmmu,domain,fmmu_logical_start_address,tx_size); |
201 |
|
202 ec_fmmu_config_domain(fmmu, domain, fmmu_logical_start_address, tx_size); |
200 ec_mutex_unlock(&sc->master->master_mutex); |
203 ec_mutex_unlock(&sc->master->master_mutex); |
201 |
204 |
202 ++sc->used_fmmus; |
205 sc->used_fmmus++; |
203 return fmmu->domain_address; |
206 return fmmu->domain_address; |
204 } |
207 } |
205 |
208 |
206 /*****************************************************************************/ |
209 /*****************************************************************************/ |
207 |
210 |