master/slave_config.c
changeset 2635 42b62867574d
parent 2634 f859d567f94e
parent 2620 0e4d098db815
equal deleted inserted replaced
2634:f859d567f94e 2635:42b62867574d
    68     sc->alias = alias;
    68     sc->alias = alias;
    69     sc->position = position;
    69     sc->position = position;
    70     sc->vendor_id = vendor_id;
    70     sc->vendor_id = vendor_id;
    71     sc->product_code = product_code;
    71     sc->product_code = product_code;
    72     sc->watchdog_divider = 0; // use default
    72     sc->watchdog_divider = 0; // use default
       
    73     sc->allow_overlapping_pdos = 0; // default not allowed
    73     sc->watchdog_intervals = 0; // use default
    74     sc->watchdog_intervals = 0; // use default
    74 
    75 
    75     sc->slave = NULL;
    76     sc->slave = NULL;
    76 
    77 
    77     for (i = 0; i < EC_MAX_SYNC_MANAGERS; i++)
    78     for (i = 0; i < EC_MAX_SYNC_MANAGERS; i++)
   179 
   180 
   180     // FMMU configuration already prepared?
   181     // FMMU configuration already prepared?
   181     for (i = 0; i < sc->used_fmmus; i++) {
   182     for (i = 0; i < sc->used_fmmus; i++) {
   182         fmmu = &sc->fmmu_configs[i];
   183         fmmu = &sc->fmmu_configs[i];
   183         if (fmmu->domain == domain && fmmu->sync_index == sync_index)
   184         if (fmmu->domain == domain && fmmu->sync_index == sync_index)
   184             return fmmu->logical_start_address;
   185             return fmmu->logical_domain_offset;
   185     }
   186     }
   186 
   187 
   187     if (sc->used_fmmus == EC_MAX_FMMUS) {
   188     if (sc->used_fmmus == EC_MAX_FMMUS) {
   188         EC_CONFIG_ERR(sc, "FMMU limit reached!\n");
   189         EC_CONFIG_ERR(sc, "FMMU limit reached!\n");
   189         return -EOVERFLOW;
   190         return -EOVERFLOW;
   190     }
   191     }
   191 
   192 
   192     fmmu = &sc->fmmu_configs[sc->used_fmmus++];
   193     fmmu = &sc->fmmu_configs[sc->used_fmmus];
   193 
   194 
   194     down(&sc->master->master_sem);
   195     down(&sc->master->master_sem);
   195     ec_fmmu_config_init(fmmu, sc, domain, sync_index, dir);
   196     ec_fmmu_config_init(fmmu, sc, domain, sync_index, dir);
       
   197 
       
   198 #if 0 //TODO overlapping PDOs
       
   199     // Overlapping PDO Support from 4751747d4e6d
       
   200     // FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME
       
   201     // parent code does not call ec_fmmu_config_domain
       
   202     // FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME
       
   203     fmmu_logical_start_address = domain->tx_size;
       
   204     tx_size = fmmu->data_size;
       
   205 
       
   206     // FIXME is it enough to take only the *previous* FMMU into account?
       
   207 
       
   208     // FIXME Need to qualify allow_overlapping_pdos with slave->sii.general_flags.enable_not_lrw
       
   209 
       
   210     if (sc->allow_overlapping_pdos && sc->used_fmmus > 0) {
       
   211         prev_fmmu = &sc->fmmu_configs[sc->used_fmmus - 1];
       
   212         if (fmmu->dir != prev_fmmu->dir && prev_fmmu->tx_size != 0) {
       
   213             // prev fmmu has opposite direction
       
   214             // and is not already paired with prev-prev fmmu
       
   215             old_prev_tx_size = prev_fmmu->tx_size;
       
   216             prev_fmmu->tx_size = max(fmmu->data_size, prev_fmmu->data_size);
       
   217             domain->tx_size += prev_fmmu->tx_size - old_prev_tx_size;
       
   218             tx_size = 0;
       
   219             fmmu_logical_start_address = prev_fmmu->logical_domain_offset;
       
   220         }
       
   221     }
       
   222 
       
   223     ec_fmmu_config_domain(fmmu, domain, fmmu_logical_start_address, tx_size);
       
   224     // Overlapping PDO Support from 4751747d4e6d
       
   225 #endif
       
   226 
       
   227     sc->used_fmmus++;
   196     up(&sc->master->master_sem);
   228     up(&sc->master->master_sem);
   197 
   229 
   198     return fmmu->logical_start_address;
   230     return fmmu->logical_domain_offset;
   199 }
   231 }
   200 
   232 
   201 /*****************************************************************************/
   233 /*****************************************************************************/
   202 
   234 
   203 /** Attaches the configuration to the addressed slave object.
   235 /** Attaches the configuration to the addressed slave object.
   274 
   306 
   275         // invalidate processing register request
   307         // invalidate processing register request
   276         list_for_each_entry(reg, &sc->reg_requests, list) {
   308         list_for_each_entry(reg, &sc->reg_requests, list) {
   277             if (sc->slave->fsm.reg_request == reg) {
   309             if (sc->slave->fsm.reg_request == reg) {
   278                 sc->slave->fsm.reg_request = NULL;
   310                 sc->slave->fsm.reg_request = NULL;
       
   311                 EC_SLAVE_WARN(sc->slave, "Aborting register request,"
       
   312                         " slave is detaching.\n");
       
   313                 reg->state = EC_INT_REQUEST_FAILURE;
       
   314                 wake_up_all(&sc->slave->master->request_queue);
   279                 break;
   315                 break;
   280             }
   316             }
   281         }
   317         }
   282 
   318 
   283         sc->slave = NULL;
   319         sc->slave = NULL;
   515     }
   551     }
   516 
   552 
   517     return NULL;
   553     return NULL;
   518 }
   554 }
   519 
   555 
       
   556 /*****************************************************************************/
       
   557 
       
   558 /** Expires any requests that have been started on a detached slave.
       
   559  */
       
   560 void ec_slave_config_expire_disconnected_requests(
       
   561         ec_slave_config_t *sc /**< Slave configuration. */
       
   562         )
       
   563 {
       
   564     ec_sdo_request_t *sdo_req;
       
   565     ec_reg_request_t *reg_req;
       
   566 
       
   567     if (sc->slave) { return; }
       
   568     
       
   569     list_for_each_entry(sdo_req, &sc->sdo_requests, list) {
       
   570         if (sdo_req->state == EC_INT_REQUEST_QUEUED ||
       
   571                 sdo_req->state == EC_INT_REQUEST_BUSY) {
       
   572             EC_CONFIG_DBG(sc, 1, "Aborting SDO request; no slave attached.\n");
       
   573             sdo_req->state = EC_INT_REQUEST_FAILURE;
       
   574         }
       
   575     }
       
   576     
       
   577     list_for_each_entry(reg_req, &sc->reg_requests, list) {
       
   578         if (reg_req->state == EC_INT_REQUEST_QUEUED ||
       
   579                 reg_req->state == EC_INT_REQUEST_BUSY) {
       
   580             EC_CONFIG_DBG(sc, 1, "Aborting register request; no slave attached.\n");
       
   581             reg_req->state = EC_INT_REQUEST_FAILURE;
       
   582         }
       
   583     }
       
   584 }
       
   585 
   520 /******************************************************************************
   586 /******************************************************************************
   521  *  Application interface
   587  *  Application interface
   522  *****************************************************************************/
   588  *****************************************************************************/
   523 
   589 
   524 int ecrt_slave_config_sync_manager(ec_slave_config_t *sc, uint8_t sync_index,
   590 int ecrt_slave_config_sync_manager(ec_slave_config_t *sc, uint8_t sync_index,
   554     EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, divider = %u, intervals = %u)\n",
   620     EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, divider = %u, intervals = %u)\n",
   555             __func__, sc, divider, intervals);
   621             __func__, sc, divider, intervals);
   556 
   622 
   557     sc->watchdog_divider = divider;
   623     sc->watchdog_divider = divider;
   558     sc->watchdog_intervals = intervals;
   624     sc->watchdog_intervals = intervals;
       
   625 }
       
   626 
       
   627 /*****************************************************************************/
       
   628 
       
   629 void ecrt_slave_config_overlapping_pdos(ec_slave_config_t *sc,
       
   630         uint8_t allow_overlapping_pdos )
       
   631 {
       
   632     EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, allow_overlapping_pdos = %u)\n",
       
   633                 __func__, sc, allow_overlapping_pdos);
       
   634 
       
   635     sc->allow_overlapping_pdos = allow_overlapping_pdos;
   559 }
   636 }
   560 
   637 
   561 /*****************************************************************************/
   638 /*****************************************************************************/
   562 
   639 
   563 int ecrt_slave_config_pdo_assign_add(ec_slave_config_t *sc,
   640 int ecrt_slave_config_pdo_assign_add(ec_slave_config_t *sc,