sr_board_0x.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2013, Shadow Robot Company, All rights reserved.
00003  * 
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Lesser General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 3.0 of the License, or (at your option) any later version.
00008  * 
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00012  * Lesser General Public License for more details.
00013  * 
00014  * You should have received a copy of the GNU Lesser General Public
00015  * License along with this library.
00016  */
00017 
00025 #include <sr_ronex_drivers/sr_board_0x.h>
00026 
00027 #include <ros_ethercat_hardware/ethercat_hardware.h>
00028 
00029 #include <sstream>
00030 #include <iomanip>
00031 #include <boost/foreach.hpp>
00032 
00033 #include <math.h>
00034 
00035 // TODO(shadow): only for testing purposes (it will be read from eeprom)
00036 #define ETHERCAT_COMMAND_DATA_ADDRESS               0x1000
00037 
00038 PLUGINLIB_EXPORT_CLASS(SrBoard0X, EthercatDevice);
00039 
00040 void SrBoard0X::construct(EtherCAT_SlaveHandler *sh, int &start_address)
00041 {
00042   sh_ = sh;
00043 
00044   // TODO(shadow): only for testing Shadow Robot boards. We read the number of inputs and outputs from the second half
00045   // of the product code
00046   // This should ideally be done in standard_ethercat_device in construct, by reading the inputs and outputs
00047   // parameters from the eeprom of the ethercat device.
00048   // This is not implemented yet neither in the driver nor in the slave (shadow board) firmware
00049   n_digital_outputs = ((sh->get_product_code() & 0x00000F00) >>  8) * 2;
00050   n_digital_inputs = ((sh->get_product_code() & 0x00000F00) >>  8);
00051   n_analog_outputs = ((sh->get_product_code() & 0x000000F0) >>  4);
00052   n_analog_inputs = ((sh->get_product_code() & 0x0000000F));
00053   n_PWM_outputs = n_digital_outputs / 2;
00054 
00055   command_base_ = start_address;
00056   command_size_ = ((n_digital_outputs/16 + 1) * 2) + (n_PWM_outputs * 4) + (n_analog_outputs * 2);
00057 
00058   start_address += command_size_;
00059 
00060   status_base_ = start_address;
00061   status_size_ = ((n_digital_inputs/16 + 1) * 2) + (n_analog_inputs * 2);
00062 
00063   start_address += status_size_;
00064 
00065 
00066   // ETHERCAT_COMMAND_DATA
00067   //
00068   // This is for data going TO the board
00069   //
00070   ROS_INFO("First FMMU (command) : start_address : 0x%08X ; size : %3d bytes ; phy addr : 0x%08X", command_base_,
00071            command_size_, static_cast<int>(ETHERCAT_COMMAND_DATA_ADDRESS) );
00072   EC_FMMU *commandFMMU = new EC_FMMU( command_base_,                  // Logical Start Address   (in ROS address space?)
00073                                       command_size_,
00074                                       0x00,                           // Logical Start Bit
00075                                       0x07,                           // Logical End Bit
00076                                       ETHERCAT_COMMAND_DATA_ADDRESS,  // Physical Start Address(in ET1200 addr space?)
00077                                       0x00,                           // Physical Start Bit
00078                                       false,                          // Read Enable
00079                                       true,                           // Write Enable
00080                                       true);                          // Channel Enable
00081 
00082 
00083   // WARNING!!!
00084   // We are leaving (command_size_ * 4) bytes in the physical memory of the device, but strictly we only need to
00085   // leave (command_size_ * 3). This change should be done in the firmware as well, otherwise it won't work.
00086   // This triple buffer is needed in the ethercat devices to work in EC_BUFFERED mode (in opposition to the other mode
00087   // EC_QUEUED, the so called mailbox mode)
00088 
00089   // ETHERCAT_STATUS_DATA
00090   //
00091   // This is for data coming FROM the board
00092   //
00093   ROS_INFO("Second FMMU (status) : start_address : 0x%08X ; size : %3d bytes ; phy addr : 0x%08X", status_base_,
00094            status_size_, static_cast<int>(ETHERCAT_COMMAND_DATA_ADDRESS + command_size_) );
00095   EC_FMMU *statusFMMU = new EC_FMMU(  status_base_,
00096                                       status_size_,
00097                                       0x00,
00098                                       0x07,
00099                                       ETHERCAT_COMMAND_DATA_ADDRESS + (command_size_ * 4),
00100                                       0x00,
00101                                       true,
00102                                       false,
00103                                       true);
00104 
00105 
00106   EtherCAT_FMMU_Config *fmmu = new EtherCAT_FMMU_Config(2);
00107 
00108   (*fmmu)[0] = *commandFMMU;
00109   (*fmmu)[1] = *statusFMMU;
00110 
00111   sh->set_fmmu_config(fmmu);
00112 
00113   EtherCAT_PD_Config *pd = new EtherCAT_PD_Config(2);
00114 
00115   (*pd)[0] = EC_SyncMan(ETHERCAT_COMMAND_DATA_ADDRESS, command_size_, EC_BUFFERED, EC_WRITTEN_FROM_MASTER);
00116   (*pd)[1] = EC_SyncMan(ETHERCAT_COMMAND_DATA_ADDRESS + (command_size_ * 4), status_size_, EC_BUFFERED);
00117 
00118 
00119   (*pd)[0].ChannelEnable = true;
00120   (*pd)[0].ALEventEnable = true;
00121   (*pd)[0].WriteEvent    = true;
00122 
00123   (*pd)[1].ChannelEnable = true;
00124 
00125   sh->set_pd_config(pd);
00126 
00127   ROS_INFO("status_size_ : %d ; command_size_ : %d", status_size_, command_size_);
00128 
00129   ROS_INFO("Finished constructing the SrBoard0X driver");
00130 }
00131 
00132 void SrBoard0X::packCommand(unsigned char *buffer, bool halt, bool reset)
00133 {
00134   cod_decod_manager_->build_command(buffer);
00135 }
00136 
00137 bool SrBoard0X::unpackState(unsigned char *this_buffer, unsigned char *prev_buffer)
00138 {
00139   unsigned char *status_data_ptr;
00140 
00141   // Pointer to the beginning of the status data in the buffer
00142   status_data_ptr = this_buffer + command_size_;
00143 
00144   cod_decod_manager_->update(status_data_ptr);
00145 
00146   return true;
00147 }
00148 
00149 


sr_ronex_drivers
Author(s): Ugo Cupcic, Toni Oliver, Mark Pitchless
autogenerated on Thu Jun 6 2019 21:22:00