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 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 only for testing Shadow Robot boards. We read the number of inputs and outputs from the second half of the product code
00045   //This should ideally be done in standard_ethercat_device in construct, by reading the inputs and outputs
00046   //parameters from the eeprom of the ethercat device.
00047   //This is not implemented yet neither in the driver nor in the slave (shadow board) firmware
00048   n_digital_outputs = ((sh->get_product_code() & 0x00000F00) >>  8) * 2;
00049   n_digital_inputs = ((sh->get_product_code() & 0x00000F00) >>  8);
00050   n_analog_outputs = ((sh->get_product_code() & 0x000000F0) >>  4);
00051   n_analog_inputs = ((sh->get_product_code() & 0x0000000F));
00052   n_PWM_outputs = n_digital_outputs / 2;
00053 
00054   command_base_ = start_address;
00055   command_size_ = ((n_digital_outputs/16 + 1) * 2) + (n_PWM_outputs * 4) + (n_analog_outputs * 2);
00056 
00057   start_address += command_size_;
00058 
00059   status_base_ = start_address;
00060   status_size_ = ((n_digital_inputs/16 + 1) * 2) + (n_analog_inputs * 2);
00061 
00062   start_address += status_size_;
00063 
00064 
00065   // ETHERCAT_COMMAND_DATA
00066   //
00067   // This is for data going TO the board
00068   //
00069   ROS_INFO("First FMMU (command) : start_address : 0x%08X ; size : %3d bytes ; phy addr : 0x%08X", command_base_, command_size_,
00070            static_cast<int>(ETHERCAT_COMMAND_DATA_ADDRESS) );
00071   EC_FMMU *commandFMMU = new EC_FMMU( command_base_,                                                  // Logical Start Address    (in ROS address space?)
00072                                       command_size_,
00073                                       0x00,                                                           // Logical Start Bit
00074                                       0x07,                                                           // Logical End Bit
00075                                       ETHERCAT_COMMAND_DATA_ADDRESS,                                  // Physical Start Address   (in ET1200 address space?)
00076                                       0x00,                                                           // Physical Start Bit
00077                                       false,                                                          // Read Enable
00078                                       true,                                                           // Write Enable
00079                                       true                                                            // Channel Enable
00080                                      );
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 EC_QUEUED, the so called mailbox mode)
00087 
00088   // ETHERCAT_STATUS_DATA
00089   //
00090   // This is for data coming FROM the board
00091   //
00092   ROS_INFO("Second FMMU (status) : start_address : 0x%08X ; size : %3d bytes ; phy addr : 0x%08X", status_base_, status_size_,
00093            static_cast<int>(ETHERCAT_COMMAND_DATA_ADDRESS + command_size_) );
00094   EC_FMMU *statusFMMU = new EC_FMMU(  status_base_,
00095                                       status_size_,
00096                                       0x00,
00097                                       0x07,
00098                                       ETHERCAT_COMMAND_DATA_ADDRESS + (command_size_ * 4),
00099                                       0x00,
00100                                       true,
00101                                       false,
00102                                       true);
00103 
00104 
00105   EtherCAT_FMMU_Config *fmmu = new EtherCAT_FMMU_Config(2);
00106 
00107   (*fmmu)[0] = *commandFMMU;
00108   (*fmmu)[1] = *statusFMMU;
00109 
00110   sh->set_fmmu_config(fmmu);
00111 
00112   EtherCAT_PD_Config *pd = new EtherCAT_PD_Config(2);
00113 
00114   (*pd)[0] = EC_SyncMan(ETHERCAT_COMMAND_DATA_ADDRESS,                             command_size_,    EC_BUFFERED, EC_WRITTEN_FROM_MASTER);
00115   (*pd)[1] = EC_SyncMan(ETHERCAT_COMMAND_DATA_ADDRESS + (command_size_ * 4),              status_size_,     EC_BUFFERED);
00116 
00117 
00118   (*pd)[0].ChannelEnable = true;
00119   (*pd)[0].ALEventEnable = true;
00120   (*pd)[0].WriteEvent    = true;
00121 
00122   (*pd)[1].ChannelEnable = true;
00123 
00124   sh->set_pd_config(pd);
00125 
00126   ROS_INFO("status_size_ : %d ; command_size_ : %d", status_size_, command_size_);
00127 
00128   ROS_INFO("Finished constructing the SrBoard0X driver");
00129 }
00130 
00131 void SrBoard0X::packCommand(unsigned char *buffer, bool halt, bool reset)
00132 {
00133   cod_decod_manager_->build_command(buffer);
00134 }
00135 
00136 bool SrBoard0X::unpackState(unsigned char *this_buffer, unsigned char *prev_buffer)
00137 {
00138   unsigned char *status_data_ptr;
00139 
00140   //Pointer to the beginning of the status data in the buffer
00141   status_data_ptr = this_buffer + command_size_;
00142 
00143   cod_decod_manager_->update(status_data_ptr);
00144 
00145   return true;
00146 }
00147 
00148 


sr_ronex_drivers
Author(s): Ugo Cupcic, Toni Oliver, Mark Pitchless
autogenerated on Fri Aug 28 2015 13:12:23