Пример #1
0
/** Initializes a sync manager configuration page.
 *
 * The referenced memory (\a data) must be at least \a EC_SYNC_SIZE bytes.
 */
void ec_sync_page(
        const ec_sync_t *sync, /**< Sync manager. */
        uint8_t sync_index, /**< Index of the sync manager. */
        uint16_t data_size, /**< Data size. */
        const ec_sync_config_t *sync_config, /**< Configuration. */
        uint8_t pdo_xfer, /**< Non-zero, if PDOs will be transferred via this
                            sync manager. */
        uint8_t *data /**> Configuration memory. */
        )
{
    // enable only if (SII enable is set or PDO xfer)
    // and size is > 0 and SM is not virtual
    uint16_t enable = ((sync->enable & 0x01) || pdo_xfer)
                        && data_size
                        && ((sync->enable & 0x04) == 0);
    uint8_t control = sync->control_register;

    if (sync_config) {

        switch (sync_config->dir) {
            case EC_DIR_OUTPUT:
            case EC_DIR_INPUT:
                EC_WRITE_BIT(&control, 2,
                        sync_config->dir == EC_DIR_OUTPUT ? 1 : 0);
                EC_WRITE_BIT(&control, 3, 0);
                break;
            default:
                break;
        }

        switch (sync_config->watchdog_mode) {
            case EC_WD_ENABLE:
            case EC_WD_DISABLE:
                EC_WRITE_BIT(&control, 6,
                        sync_config->watchdog_mode == EC_WD_ENABLE);
                break;
            default:
                break;
        }
    }

    EC_SLAVE_DBG(sync->slave, 1, "SM%u: Addr 0x%04X, Size %3u,"
            " Ctrl 0x%02X, En %u\n",
            sync_index, sync->physical_start_address,
            data_size, control, enable);

    EC_WRITE_U16(data,     sync->physical_start_address);
    EC_WRITE_U16(data + 2, data_size);
    EC_WRITE_U8 (data + 4, control);
    EC_WRITE_U8 (data + 5, 0x00); // status byte (read only)
    EC_WRITE_U16(data + 6, enable);
}
Пример #2
0
void lcec_el2202_write(struct lcec_slave *slave, long period) {
  lcec_master_t *master = slave->master;
  uint8_t *pd = master->process_data;

  lcec_el2202_data_t *hal_data = (lcec_el2202_data_t *) slave->hal_data;
  lcec_el2202_chan_t *chan;

  int i;

  for (i=0; i<LCEC_EL2202_CHANS; i++) {
    chan = &hal_data->chans[i];

    // set output
    EC_WRITE_BIT(&pd[chan->out_offs], chan->out_bitp, *(chan->out));
    // set tristate
    EC_WRITE_BIT(&pd[chan->tristate_offs], chan->tristate_bitp, *(chan->tristate));
  }
}
Пример #3
0
void lcec_el5152_write(struct lcec_slave *slave, long period) {
  lcec_master_t *master = slave->master;
  lcec_el5152_data_t *hal_data = (lcec_el5152_data_t *) slave->hal_data;
  uint8_t *pd = master->process_data;
  int i;
  lcec_el5152_chan_t *chan;

  // set outputs
  for (i=0; i<LCEC_EL5152_CHANS; i++) {
    chan = &hal_data->chans[i];

    // set output data
    EC_WRITE_BIT(&pd[chan->set_count_pdo_os], chan->set_count_pdo_bp, *(chan->set_raw_count));
    EC_WRITE_S32(&pd[chan->set_count_val_pdo_os], *(chan->set_raw_count_val));
  }
}
Пример #4
0
void lcec_el7342_write(struct lcec_slave *slave, long period) {
  lcec_master_t *master = slave->master;
  lcec_el7342_data_t *hal_data = (lcec_el7342_data_t *) slave->hal_data;
  uint8_t *pd = master->process_data;
  int i;
  lcec_el7342_chan_t *chan;
  double tmpval, tmpdc, raw_val;

  // set outputs
  for (i=0; i<LCEC_EL7342_CHANS; i++) {
    chan = &hal_data->chans[i];

    // validate duty cycle limits, both limits must be between
    // 0.0 and 1.0 (inclusive) and max must be greater then min
    if (*(chan->dcm_max_dc) > 1.0) {
      *(chan->dcm_max_dc) = 1.0;
    }
    if (*(chan->dcm_min_dc) > *(chan->dcm_max_dc)) {
      *(chan->dcm_min_dc) = *(chan->dcm_max_dc);
    }
    if (*(chan->dcm_min_dc) < -1.0) {
      *(chan->dcm_min_dc) = -1.0;
    }
    if (*(chan->dcm_max_dc) < *(chan->dcm_min_dc)) {
      *(chan->dcm_max_dc) = *(chan->dcm_min_dc);
    }

    // do scale calcs only when scale changes
    if (*(chan->dcm_scale) != chan->dcm_old_scale) {
      // validate the new scale value
      if ((*(chan->dcm_scale) < 1e-20) && (*(chan->dcm_scale) > -1e-20)) {
        // value too small, divide by zero is a bad thing
        *(chan->dcm_scale) = 1.0;
      }
      // get ready to detect future scale changes
      chan->dcm_old_scale = *(chan->dcm_scale);
      // we will need the reciprocal
      chan->dcm_scale_recip = 1.0 / *(chan->dcm_scale);
    }

    // get command
    tmpval = *(chan->dcm_value);
    if (*(chan->dcm_absmode) && (tmpval < 0)) {
      tmpval = -tmpval;
    }

    // convert value command to duty cycle
    tmpdc = tmpval * chan->dcm_scale_recip + *(chan->dcm_offset);
    if (tmpdc < *(chan->dcm_min_dc)) {
      tmpdc = *(chan->dcm_min_dc);
    }
    if (tmpdc > *(chan->dcm_max_dc)) {
      tmpdc = *(chan->dcm_max_dc);
    }

    // set output values
    if (*(chan->dcm_enable) == 0) {
      raw_val = 0;
      *(chan->dcm_curr_dc) = 0;
    } else {
      raw_val = (double)0x7fff * tmpdc;
      if (raw_val > (double)0x7fff) {
        raw_val = (double)0x7fff;
      }
      if (raw_val < (double)-0x7fff) {
        raw_val = (double)-0x7fff;
      }
      *(chan->dcm_curr_dc) = tmpdc;
    }

    // update value
    *(chan->dcm_raw_val) = (int32_t)raw_val;

    // set output data
    EC_WRITE_BIT(&pd[chan->set_count_pdo_os], chan->set_count_pdo_bp, *(chan->set_raw_count));
    EC_WRITE_BIT(&pd[chan->ena_latch_ext_pos_pdo_os], chan->ena_latch_ext_pos_pdo_bp, *(chan->ena_latch_ext_pos));
    EC_WRITE_BIT(&pd[chan->ena_latch_ext_neg_pdo_os], chan->ena_latch_ext_neg_pdo_bp, *(chan->ena_latch_ext_neg));
    EC_WRITE_S16(&pd[chan->set_count_val_pdo_os], *(chan->set_raw_count_val));

    EC_WRITE_BIT(&pd[chan->dcm_ena_pdo_os], chan->dcm_ena_pdo_bp, *(chan->dcm_enable));
    EC_WRITE_BIT(&pd[chan->dcm_reset_pdo_os], chan->dcm_reset_pdo_bp, *(chan->dcm_reset));
    EC_WRITE_BIT(&pd[chan->dcm_reduce_torque_pdo_os], chan->dcm_reduce_torque_pdo_bp, *(chan->dcm_reduce_torque));
    EC_WRITE_S16(&pd[chan->dcm_velo_pdo_os], (int16_t)raw_val);
  }
}
Пример #5
0
void lcec_el7041_1000_write(struct lcec_slave *s, long period) {
  lcec_master_t *m = s->master;
  lcec_el7041_1000_data_t *hd = (lcec_el7041_1000_data_t *) s->hal_data;
  uint8_t *pd = m->process_data;
  double tmpval, tmpdc, raw_val;
  int enable_on_edge;

  // set outputs

  // check for enable edge
  enable_on_edge = *(hd->dcm_enable) && !hd->last_dcm_enable;
  hd->last_dcm_enable = *(hd->dcm_enable);

  // check for autoreset
  if (enable_on_edge && hd->internal_fault) {
    hd->fault_reset_retry = 1;
    hd->fault_reset_state = 1;
    hd->fault_reset_cycle = 0;
  }

  // validate duty cycle limits, both limits must be between
  // 0.0 and 1.0 (inclusive) and max must be greater then min
  if (*(hd->dcm_max_dc) > 1.0) {
      *(hd->dcm_max_dc) = 1.0;
  }
  if (*(hd->dcm_min_dc) > *(hd->dcm_max_dc)) {
      *(hd->dcm_min_dc) = *(hd->dcm_max_dc);
  }
  if (*(hd->dcm_min_dc) < -1.0) {
      *(hd->dcm_min_dc) = -1.0;
  }
  if (*(hd->dcm_max_dc) < *(hd->dcm_min_dc)) {
      *(hd->dcm_max_dc) = *(hd->dcm_min_dc);
  }

  // do scale calcs only when scale changes
  if (*(hd->dcm_scale) != hd->dcm_old_scale) {
      // validate the new scale value
      if ((*(hd->dcm_scale) < 1e-20) && (*(hd->dcm_scale) > -1e-20)) {
              // value too small, divide by zero is a bad thing
              *(hd->dcm_scale) = 1.0;
      }
      // get ready to detect future scale changes
      hd->dcm_old_scale = *(hd->dcm_scale);
      // we will need the reciprocal
      hd->dcm_scale_recip = 1.0 / *(hd->dcm_scale);
  }

  // get command
  tmpval = *(hd->dcm_value);
  if (*(hd->dcm_absmode) && (tmpval < 0)) {
      tmpval = -tmpval;
  }

  // convert value command to duty cycle
  tmpdc = tmpval * hd->dcm_scale_recip + *(hd->dcm_offset);
  if (tmpdc < *(hd->dcm_min_dc)) {
      tmpdc = *(hd->dcm_min_dc);
  }
  if (tmpdc > *(hd->dcm_max_dc)) {
      tmpdc = *(hd->dcm_max_dc);
  }

  // set output values
  if (*(hd->dcm_enable) == 0) {
      raw_val = 0;
      *(hd->dcm_curr_dc) = 0;
  } else {
      raw_val = (double)0x7fff * tmpdc;
      if (raw_val > (double)0x7fff) {
              raw_val = (double)0x7fff;
      }
      if (raw_val < (double)-0x7fff) {
              raw_val = (double)-0x7fff;
      }
      *(hd->dcm_curr_dc) = tmpdc;
  }

  // update value
  *(hd->dcm_raw_val) = (int32_t)raw_val;

  // fault reset
  if (*(hd->fault_reset)) {
    *(hd->dcm_reset) = 1;
  }

  if (hd->fault_reset_retry > 0) {
    if (hd->fault_reset_state) {
      *(hd->dcm_reset) = 1;
    }
  } else {
    if (*(hd->dcm_enable)) {
      *(hd->dcm_reset) = 0;
    }
    *(hd->fault_reset) = 0;
  }

  // set output data
  EC_WRITE_BIT(&pd[hd->set_count_pdo_os], hd->set_count_pdo_bp, *(hd->set_raw_count));
  EC_WRITE_BIT(&pd[hd->ena_latch_c_pdo_os], hd->ena_latch_c_pdo_bp, *(hd->ena_latch_c));
  EC_WRITE_BIT(&pd[hd->ena_latch_ext_pos_pdo_os], hd->ena_latch_ext_pos_pdo_bp, *(hd->ena_latch_ext_pos));
  EC_WRITE_BIT(&pd[hd->ena_latch_ext_neg_pdo_os], hd->ena_latch_ext_neg_pdo_bp, *(hd->ena_latch_ext_neg));
  EC_WRITE_S16(&pd[hd->set_count_val_pdo_os], *(hd->set_raw_count_val));

  EC_WRITE_BIT(&pd[hd->dcm_ena_pdo_os], hd->dcm_ena_pdo_bp, *(hd->dcm_enable));
  EC_WRITE_BIT(&pd[hd->dcm_reset_pdo_os], hd->dcm_reset_pdo_bp, *(hd->dcm_reset));
  EC_WRITE_BIT(&pd[hd->dcm_reduce_torque_pdo_os], hd->dcm_reduce_torque_pdo_bp, *(hd->dcm_reduce_torque));
  EC_WRITE_S16(&pd[hd->dcm_velo_pdo_os], (int16_t)raw_val);
}