this_node.c
Go to the documentation of this file.
00001 //
00002 // © 2010 Shadow Robot Company Limited.
00003 //
00004 // FileName:        this_node.c
00005 // Dependencies:    
00006 // Processor:       PIC32
00007 // Compiler:        MPLAB® C32 
00008 //
00009 //  +------------------------------------------------------------------------+
00010 //  | This file is part of The Shadow Robot PIC32 firmware code base.        |
00011 //  |                                                                        |
00012 //  | It is free software: you can redistribute it and/or modify             |
00013 //  | it under the terms of the GNU General Public License as published by   |
00014 //  | the Free Software Foundation, either version 3 of the License, or      |
00015 //  | (at your option) any later version.                                    |
00016 //  |                                                                        |
00017 //  | It is distributed in the hope that it will be useful,                  |
00018 //  | but WITHOUT ANY WARRANTY; without even the implied warranty of         |
00019 //  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          |
00020 //  | GNU General Public License for more details.                           |
00021 //  |                                                                        |
00022 //  | You should have received a copy of the GNU General Public License      |
00023 //  | along with this code repository. The text of the license can be found  |
00024 //  | in Pic32/License/gpl.txt. If not, see <http://www.gnu.org/licenses/>.  |
00025 //  +------------------------------------------------------------------------+
00026 //
00027 //
00028 //
00029 //
00030 //  Doxygen
00031 //  -------
00032 //
00034 //
00036 //
00037 
00038 #include "this_node.h"
00039 #include "tests/assert_shadow.h"
00040 #include "internal_reporting/internal_reporting.h"
00041 #include "hardware/et1200/et1200_interface.h"
00042 #include <peripheral/spi.h>
00043 
00044 int64u      node_id                  = 0;
00045 int32u      global_AL_Event_Register = 0;
00046 
00047 TACTILE_SENSOR_PROTOCOL_TYPE    tactile_sensor_protocol = TACTILE_SENSOR_PROTOCOL_TYPE_INVALID;
00048 
00049 ETHERCAT_DATA_STRUCTURE_0200_PALM_EDC_COMMAND   etherCAT_command_data;              
00050 ETHERCAT_DATA_STRUCTURE_0200_PALM_EDC_STATUS    etherCAT_status_data;               
00051 
00052 ETHERCAT_CAN_BRIDGE_DATA                        can_bridge_data_from_ROS;
00053 ETHERCAT_CAN_BRIDGE_DATA                        can_bridge_data_to_ROS;
00054 
00055 
00056 #define CORE_TIMER_TO_MICROSECONDS(x) ((x) / (SYSTEM_FREQ_HZ/2000000))              //!< Convert from the number of core ticks returned by ReadCoreTimer to a real time in microseconds.
00057 
00058 
00059 
00060 #ifdef PALM_PCB_00
00061     int8u palm_EDC_0200_sensor_mapping[64] = {IGNORE, IGNORE, IGNORE, IGNORE,  FFJ4,   THJ3,   THJ1,    IGNORE,           // Channel 0
00062                                               IGNORE, IGNORE, IGNORE, IGNORE,  MFJ4,   THJ4,   THJ2,    IGNORE,           // Channel 1
00063                                               FFJ2  , MFJ2  , RFJ2  , LFJ2  ,  RFJ4,   AN0,    IGNORE,  IGNORE,           // Channel 2
00064                                               FFJ1  , MFJ1  , RFJ1  , LFJ1  ,  THJ5B,  THJ5A,  IGNORE,  IGNORE,           // Channel 3
00065                                               IGNORE, IGNORE, IGNORE, IGNORE,  WRJ1B,  WRJ1A,  IGNORE,  IGNORE,           // Channel 4
00066                                               IGNORE, IGNORE, IGNORE, IGNORE,  AN1,    LFJ4,   IGNORE,  IGNORE,           // Channel 5
00067                                               FFJ3  , MFJ3  , RFJ3  , LFJ3  ,  AN2,    LFJ5,   IGNORE,  IGNORE,           // Channel 6
00068                                               IGNORE, IGNORE, IGNORE, IGNORE,  AN3,    WRJ2,   IGNORE,  IGNORE            // Channel 7
00069                                              };
00070 #endif
00071 
00072 
00073 
00074 #ifdef PALM_PCB_01    
00075     int8u palm_EDC_0200_sensor_mapping[64] = {IGNORE, IGNORE, IGNORE, IGNORE,  FFJ4,   THJ4,   IGNORE,  IGNORE,           // Channel 0
00076                                               IGNORE, IGNORE, IGNORE, IGNORE,  MFJ4,   THJ3,   IGNORE,  IGNORE,           // Channel 1
00077                                               RFJ2  , MFJ2  , FFJ2  , LFJ2  ,  RFJ4,   AN0,    THJ1,    IGNORE,           // Channel 2
00078                                               RFJ1  , MFJ1  , FFJ1  , LFJ1  ,  THJ5B,  THJ5A,  IGNORE,  IGNORE,           // Channel 3
00079                                               IGNORE, IGNORE, IGNORE, IGNORE,  AN3,    WRJ2,   THJ2,    IGNORE,           // Channel 4
00080                                               IGNORE, IGNORE, IGNORE, IGNORE,  AN2,    LFJ4,   IGNORE,  IGNORE,           // Channel 5
00081                                               RFJ3  , MFJ3  , FFJ3  , LFJ3  ,  AN1,    LFJ5,   IGNORE,  IGNORE,           // Channel 6
00082                                               IGNORE, IGNORE, IGNORE, IGNORE,  WRJ1A,  WRJ1B,  IGNORE,  IGNORE            // Channel 7
00083                                              };
00084 #endif
00085 
00086 
00087 
00088 int32u frame_start_time = 0;                
00089 int32u idle_time_start  = 0;                
00090 
00091 
00092 
00093 
00094 LED_Class *LED_CAN1_TX;                     
00095 LED_Class *LED_CAN1_RX;                     
00096 LED_Class *LED_CAN1_ERR;                    
00097 
00098 LED_Class *LED_CAN2_TX;                     
00099 LED_Class *LED_CAN2_ERR;                    
00100 
00101 LED_Class *ET1200_AL_err_LED;               
00102 
00103 
00104 #ifdef LED_CFG_PIN
00105   LED_Class  *LED_CFG;                      
00106 
00107 
00108 #endif
00109 
00110 
00111 #ifdef LED_CAN2_RX_PIN
00112     LED_Class *LED_CAN2_RX;                 
00113 
00114 
00115 #endif
00116 
00117 
00118 int num_motor_CAN_messages_received_this_frame = 0;     
00119 
00120 
00121 
00122 void run_tests(void)
00123 {
00124     typedef_tests();
00125     simple_CAN_tests();
00126 }
00127 
00128 
00129 
00136 void approx_1ms_handler(void)
00137 {
00138     Handle_LEDs();
00139 
00140     #if AUTO_TRIGGER == 1
00141         etherCAT_command_data.EDC_command = EDC_COMMAND_SENSOR_DATA;
00142         Read_All_Sensors();
00143     #endif
00144 
00145     ClearWDT();
00146 }
00147 
00148 
00149 
00162 void initialise_this_node(void)
00163 {
00164     run_tests();                                                                            // Very important
00165 
00166 
00167                                                                                             // Initialise all of the I/O pins and peripherals.
00168     Output_Pin_Class *ET1200_chip_select    = Get_Output_Pin(ET1200_CHIP_SELECT_PIN);
00169     Output_Pin_Class *ET1200_reset          = Get_Output_Pin(ET1200_RESET_PIN);
00170     Input_Pin_Class  *ET1200_eeprom         = Get_Input_Pin (ET1200_EEPROM_PIN);
00171 
00172     SPI_simple_master_class   *SPI_port     = Init_SPI_Simple_Master(SPI_PORT);
00173     I2C_simple_master_class   *I2C_port     = Init_I2C_Simple_Master(I2C_PORT);
00174 
00175     Output_Pin_Class *SPI_cs                = Get_Output_Pin(SPI_CS_PIN);
00176     Output_Pin_Class *SPI_clock             = Get_Output_Pin(SPI_CLOCK_PIN);
00177     Output_Pin_Class *SPI_mosi              = Get_Output_Pin(SPI_MOSI_PIN);
00178     Input_Pin_Class  *ET1200_somi           = Get_Input_Pin (ET1200_SOMI_PIN);
00179 
00180 
00181     Output_Pin_Class *LED_pin_CAN1_TX       = Get_Output_Pin(LED_CAN1_TX_PIN);
00182     Output_Pin_Class *LED_pin_CAN1_RX       = Get_Output_Pin(LED_CAN1_RX_PIN);
00183     Output_Pin_Class *LED_pin_CAN1_ERR      = Get_Output_Pin(LED_CAN1_ERR_PIN);
00184 
00185     Output_Pin_Class *LED_pin_CAN2_TX       = Get_Output_Pin(LED_CAN2_TX_PIN);
00186     Output_Pin_Class *LED_pin_CAN2_ERR      = Get_Output_Pin(LED_CAN2_ERR_PIN);
00187 
00188     Output_Pin_Class *LED_pin_AL_ERR        = Get_Output_Pin(LED_AL_ERR_PIN);
00189 
00190     Output_Pin_Class *accel_CS              = Get_Output_Pin(ACCEL_CS_PIN);
00191     Pin_Set(accel_CS);
00192     
00193     LED_CAN1_TX                             = Get_LED(LED_pin_CAN1_TX);
00194     LED_CAN1_RX                             = Get_LED(LED_pin_CAN1_RX);
00195     LED_CAN1_ERR                            = Get_LED(LED_pin_CAN1_ERR);
00196 
00197     LED_CAN2_TX                             = Get_LED(LED_pin_CAN2_TX);
00198     LED_CAN2_ERR                            = Get_LED(LED_pin_CAN2_ERR);
00199 
00200     ET1200_AL_err_LED                       = Get_LED(LED_pin_AL_ERR);
00201 
00202     #ifdef LED_CFG_PIN
00203         Output_Pin_Class *LED_pin_CFG       = Get_Output_Pin(LED_CFG_PIN);
00204         LED_CFG                             = Get_LED(LED_pin_CFG);
00205     #endif
00206 
00207     #ifdef LED_CAN2_RX_PIN
00208         Output_Pin_Class *LED_pin_CAN2_RX   = Get_Output_Pin(LED_CAN2_RX_PIN);
00209         LED_CAN2_RX                         = Get_LED(LED_pin_CAN2_RX);
00210     #endif
00211 
00212 
00213     AD1PCFG = 0xFFFF;                                                                       // Set all pins to Digital, not analog.
00214     U1CON   = 0x0000;                                                                       // Disable USB
00215 
00216 
00217     ET1200_Interface_Initialise(SPI_port, I2C_port, ET1200_reset, ET1200_AL_err_LED, ET1200_eeprom, ET1200_somi, ET1200_chip_select);
00218 
00219     #if AUTO_TRIGGER == 0
00220         ET1200_Initialise();
00221         write_ET1200_register_32u(0x204, 0x100);                                            //set AL event mask to get IRQ only on SyncMan0 activity
00222     #endif
00223 
00224 
00225     init_dual_CAN();
00226 
00227 
00228 
00229 
00230     {                                                                                       // Initialise the MOSI bits for each ADC channel
00231         Input_Pins_Class *SPI_SOMI_pins      = Get_Input_Pins('E', 0, 8);
00232     
00233         Initialise_SPI_Parallel(SPI_cs, SPI_clock, SPI_mosi, SPI_SOMI_pins);
00234         SPIP_Setup_MOSI_Bits(0, 19, 0xC0000000);        // 1100 0000
00235         SPIP_Setup_MOSI_Bits(1, 19, 0xC8000000);        // 1100 1000
00236         SPIP_Setup_MOSI_Bits(2, 19, 0xD0000000);        // 1101 0000
00237         SPIP_Setup_MOSI_Bits(3, 19, 0xD8000000);        // 1101 1000
00238         SPIP_Setup_MOSI_Bits(4, 19, 0xE0000000);        // 1110 0000
00239         SPIP_Setup_MOSI_Bits(5, 19, 0xE8000000);        // 1110 1000
00240         SPIP_Setup_MOSI_Bits(6, 19, 0xF0000000);        // 1111 0000
00241         SPIP_Setup_MOSI_Bits(7, 19, 0xF8000000);        // 1111 1000
00242     }
00243 
00244 
00245     tactile_sensor_protocol = biotac_autodetect(tactile_sensor_protocol);                   // Auto-detect the tactile sensor type.
00246     tactile_sensor_protocol =    pst_autodetect(tactile_sensor_protocol);                   // Result is stored in tactile_sensor_protocol.
00247 
00248     switch (tactile_sensor_protocol)                                                        // Now initialise the tactile sensors according to the detected type.
00249     {
00250         case TACTILE_SENSOR_PROTOCOL_TYPE_PST3:             init_pst();         break;      // PST3     (new type with normal CS)
00251         case TACTILE_SENSOR_PROTOCOL_TYPE_BIOTAC_2_3:       init_biotac();      break;      // BioTac   (Syntouch)
00252 
00253         default:                                                                break;
00254     }
00255 
00256 
00257 }
00258 
00259 
00260 
00261 void Read_Commands_From_ET1200(void)
00262 {
00263     assert_dynamic(ETHERCAT_COMMAND_DATA_SIZE > 0);
00264     //read_ET1200_register_N(EC_PALM_EDC_COMMAND_PHY_BASE, ETHERCAT_COMMAND_DATA_SIZE, (int8u*)(&etherCAT_command_data));
00265     read_ET1200_register_N( ETHERCAT_COMMAND_DATA_ADDRESS,
00266                             ETHERCAT_COMMAND_DATA_SIZE,
00267                             (int8u*)(&etherCAT_command_data)  );
00268 }
00269 
00270 
00271 
00277 inline void write_status_data_To_ET1200(void)
00278 {
00279     write_ET1200_register_N(ETHERCAT_STATUS_DATA_ADDRESS, ETHERCAT_STATUS_DATA_SIZE, (int8u*)(&etherCAT_status_data));
00280 }
00281 
00282 
00283 
00290 int8u There_is_Command_From_ET1200(void)
00291 {
00292     global_AL_Event_Register = read_ET1200_register_32u(0x220);
00293     return ( ( global_AL_Event_Register & ECREG32_AL_EVENT_BIT_SYNCMANAGER_0_INTERRUPT ) != 0) ;
00294 }
00295 
00296 
00297 
00305 int8u ROS_Wants_me_to_send_CAN(void)
00306 {
00307     return ( ( global_AL_Event_Register & ECREG32_AL_EVENT_BIT_SYNCMANAGER_1_INTERRUPT ) != 0) ;
00308 }
00309 
00310 
00311 
00315 int8u not_all_motor_data_received(void)
00316 {
00317     return num_motor_CAN_messages_received_this_frame < 10;
00318 }
00319 
00320 
00321 
00326 int32u get_frame_time_us(void)
00327 {
00328     return (ReadCoreTimer() - frame_start_time) / (SYSTEM_FREQ_HZ/2000000);
00329 }
00330 
00331 
00332 
00343 void Wait_For_All_Motors_To_Send_Data(int32u timeout_us)
00344 {
00345     do
00346     {
00347         collect_motor_data_CAN_messages(CAN1);
00348         collect_motor_data_CAN_messages(CAN2);
00349     }
00350     while (  (not_all_motor_data_received())
00351           && (get_frame_time_us() < timeout_us)
00352           );
00353 }
00354 
00355 
00356 
00369 void Wait_For_Until_Frame_Time(int32u frame_time_us)
00370 {
00371     while (get_frame_time_us() <= frame_time_us)
00372     {
00373     }
00374 }
00375 
00376 
00377 
00383 int16u calculate_idle_time(void)
00384 {
00385     return CORE_TIMER_TO_MICROSECONDS(frame_start_time - idle_time_start);
00386 }
00387 
00388 
00389 
00390 
00394 void Read_All_Sensors(void)
00395 {
00396     int8u adc_channel;
00397     int8u j=0;
00398     int32u frame_time;
00399 
00400     Nop();
00401     Nop();
00402 
00403     for (j=0; j<SENSORS_NUM_0220; j++)
00404         etherCAT_status_data.sensors[j] = j;
00405 
00406     switch (tactile_sensor_protocol)                                                // Read tactile sensors before joint sensors?
00407     {                                                                               // ------------------------------------------
00408         case TACTILE_SENSOR_PROTOCOL_TYPE_PST3:
00409             break;
00410 
00411         case TACTILE_SENSOR_PROTOCOL_TYPE_BIOTAC_2_3:                               // BioTac Pac needs to be read once before joint sensors.
00412             frame_time = get_frame_time_us();
00413             biotac_read_pac(0, &etherCAT_command_data, &etherCAT_status_data);
00414             break;
00415 
00416         default:
00417             break;
00418     }
00419 
00420 
00421     j=0;
00422     for (adc_channel = 0; adc_channel < 8; ++adc_channel)                           // Now read joint sensors.
00423     {                                                                               // -----------------------
00424         switch (etherCAT_command_data.EDC_command)
00425         {
00426             case EDC_COMMAND_SENSOR_DATA: 
00427                 SPIP_max_bits = 19;
00428                 SPIP_Xceive_Fast(adc_channel);
00429                 break;
00430 
00431             case EDC_COMMAND_SENSOR_CHANNEL_NUMBERS:
00432                 SPIP_PutChannel_Numbers(adc_channel);
00433                 break;
00434 
00435             default: 
00436                 SPIP_PutChannel_Numbers(adc_channel);
00437                 break;
00438         }
00439 
00440         etherCAT_status_data.sensors[ palm_EDC_0200_sensor_mapping[j++] ] = TRANSLATE_SOMI_MCP3208(0);
00441         etherCAT_status_data.sensors[ palm_EDC_0200_sensor_mapping[j++] ] = TRANSLATE_SOMI_MCP3208(1);
00442         etherCAT_status_data.sensors[ palm_EDC_0200_sensor_mapping[j++] ] = TRANSLATE_SOMI_MCP3208(2);
00443         etherCAT_status_data.sensors[ palm_EDC_0200_sensor_mapping[j++] ] = TRANSLATE_SOMI_MCP3208(3);
00444         etherCAT_status_data.sensors[ palm_EDC_0200_sensor_mapping[j++] ] = TRANSLATE_SOMI_MCP3208(4);
00445         etherCAT_status_data.sensors[ palm_EDC_0200_sensor_mapping[j++] ] = TRANSLATE_SOMI_MCP3208(5);
00446         etherCAT_status_data.sensors[ palm_EDC_0200_sensor_mapping[j++] ] = TRANSLATE_SOMI_MCP3208(6);
00447         etherCAT_status_data.sensors[ palm_EDC_0200_sensor_mapping[j++] ] = TRANSLATE_SOMI_MCP3208(7);
00448     }
00449 
00450     #if AUTO_TRIGGER == 1
00451         etherCAT_command_data.tactile_data_type = TACTILE_SENSOR_TYPE_BIOTAC_PDC;
00452     #endif
00453 
00454 
00455     switch (tactile_sensor_protocol)                                                // Read tactile sensors after joint sensors?
00456     {                                                                               // -----------------------------------------
00457 
00458         case TACTILE_SENSOR_PROTOCOL_TYPE_PST3:                                     // PST3s are read after
00459             read_PSTs(&etherCAT_command_data, &etherCAT_status_data);
00460             break;
00461 
00462         case TACTILE_SENSOR_PROTOCOL_TYPE_BIOTAC_2_3:                               // BioTac: Hall, Misc, and Pac again are read after joint sensors.
00463             biotac_read_sensors(&etherCAT_command_data, &etherCAT_status_data);
00464 
00465             Wait_For_All_Motors_To_Send_Data(frame_time+490);                       // Use this delay time productively
00466             Wait_For_Until_Frame_Time(frame_time+500);                              // Now that we're close to the time, use a more accurate wait routine.
00467 
00468             biotac_read_pac(1, &etherCAT_command_data, &etherCAT_status_data);      // Read the Pac again at 500us to achieve 2000Hz.
00469             break;
00470 
00471         default:
00472             break;
00473     }
00474 
00475 
00476     if (etherCAT_command_data.tactile_data_type == TACTILE_SENSOR_TYPE_WHICH_SENSORS)   // Is the host asking which tactile sensor protocol we're using?
00477     {
00478         etherCAT_status_data.tactile[0].word[0] = tactile_sensor_protocol;              // Then tell it!
00479         etherCAT_status_data.tactile[1].word[0] = tactile_sensor_protocol;
00480         etherCAT_status_data.tactile[2].word[0] = tactile_sensor_protocol;
00481         etherCAT_status_data.tactile[3].word[0] = tactile_sensor_protocol;
00482         etherCAT_status_data.tactile[4].word[0] = tactile_sensor_protocol;
00483         etherCAT_status_data.tactile_data_valid = 0x001F;
00484         etherCAT_status_data.tactile_data_type = TACTILE_SENSOR_TYPE_WHICH_SENSORS;
00485     }
00486 }
00487 
00488 
00489 
00493 void zero_motor_data_packets(void)
00494 {
00495     int i;
00496 
00497     for (i=0; i<9; i++)
00498     {
00499         etherCAT_status_data.motor_data_packet[i].torque = 0;
00500         etherCAT_status_data.motor_data_packet[i].misc   = 0;
00501     }
00502 
00503     etherCAT_status_data.which_motor_data_arrived    = 0x00000000;
00504     etherCAT_status_data.which_motor_data_had_errors = 0x00000000;
00505     etherCAT_status_data.which_motors                = etherCAT_command_data.which_motors;
00506 }
00507 
00508 
00509 
00514 void Check_For_EtherCAT_Packet(void)
00515 {
00516     ET1200_Update();
00517 
00518     #if AUTO_TRIGGER == 1                                                                   // This is just for debugging.
00519         if (get_frame_time_us() > 1150)                                                     // 
00520         {                                                                                   // 
00521             frame_start_time = ReadCoreTimer();                                             // 
00522             approx_1ms_handler();                                                           // 
00523         }                                                                                   // 
00524         return;                                                                             // 
00525     #endif                                                                                  // 
00526 
00527 
00528     if (There_is_Command_From_ET1200())
00529     {   
00530         frame_start_time = ReadCoreTimer();                                                 // The frame starts NOW!
00531         approx_1ms_handler();                                                               // Normally, the EtherCAT packets are used as a 1ms time base.
00532         Service_EtherCAT_Packet();
00533         return;
00534     }
00535 
00536     if (get_frame_time_us() > 1300)                                                         // If there are no EtherCAT packets,
00537     {                                                                                       // then we need to trigger approx_1ms_handler()
00538         frame_start_time = ReadCoreTimer();                                                 // And so we think of a frame starting now.
00539         approx_1ms_handler();                                                               // by time instead. 
00540         return;
00541     }
00542 }
00543 
00544 
00545 
00550 void Service_EtherCAT_Packet(void)
00551 {
00552     Read_Commands_From_ET1200();                                                            // Read the command data
00553 
00554 
00555     switch (etherCAT_command_data.EDC_command)
00556     {
00557         case EDC_COMMAND_SENSOR_DATA:                                                       // Normal Command / Status packet
00558                                                                                             // ------------------------------
00559 
00560                                                                                             // This EDC_command is handled,
00561             LED_Off(ET1200_AL_err_LED);                                                     // so extinguish the Application Layer LED
00562 
00563             send_CAN_request_data_message( etherCAT_command_data.which_motors,
00564                                            etherCAT_command_data.from_motor_data_type);     // Start of frame message
00565 
00566 
00567             zero_motor_data_packets();                                                      // Housekeeping
00568 
00569             Read_All_Sensors();                                                             // Read all joint and tactile sensors.
00570             num_motor_CAN_messages_received_this_frame = 0;
00571             Wait_For_All_Motors_To_Send_Data(600);                                          // Wait for 600us max.
00572             Send_Data_To_Motors(&etherCAT_command_data);                                    // Send CAN messages to motors
00573 
00574             etherCAT_status_data.EDC_command  = EDC_COMMAND_SENSOR_DATA;                    // FIXME: I don't think this calculation is correct
00575             etherCAT_status_data.idle_time_us = calculate_idle_time();                      // 
00576 
00577             write_status_data_To_ET1200();
00578             idle_time_start = ReadCoreTimer();                                              // Idle time begins now because the status data
00579                                                                                             // has been written to the ET1200. The next EtherCAT
00580                                                                                             // packet can arrive any time after this.
00581             break;
00582 
00583 
00584 
00585         case EDC_COMMAND_CAN_DIRECT_MODE:                                                   // CAN Bridge packet
00586                                                                                             // -----------------
00587 
00588                                                                                             // This EDC_command is handled,
00589             LED_Off(ET1200_AL_err_LED);                                                     // so extinguish the Application Layer LED
00590 
00591             if ( ROS_Wants_me_to_send_CAN() )
00592             {
00593                 read_ET1200_register_N(ETHERCAT_CAN_BRIDGE_DATA_COMMAND_ADDRESS, ETHERCAT_CAN_BRIDGE_DATA_SIZE, (int8u*)(&can_bridge_data_from_ROS));
00594                 send_CAN_message_from_ROS();
00595                 global_AL_Event_Register = read_ET1200_register_32u(0x220);
00596             }
00597 
00598             etherCAT_status_data.EDC_command  = EDC_COMMAND_SENSOR_DATA;
00599             etherCAT_status_data.idle_time_us = calculate_idle_time();                      // FIXME: I don't think this calculation is correct
00600             write_status_data_To_ET1200();                                                  // 
00601 
00602             Wait_For_Until_Frame_Time(600);                                                 // Give the node a little time to respond, and we might be able
00603                                                                                             // to get the reply message back into the very next EtherCAT packet.
00604 
00605             collect_one_CAN_message();                                                      // From either CAN bus
00606 
00607             write_ET1200_register_N(ETHERCAT_CAN_BRIDGE_DATA_STATUS_ADDRESS, ETHERCAT_CAN_BRIDGE_DATA_SIZE, (int8u*)(&can_bridge_data_to_ROS));
00608             idle_time_start = ReadCoreTimer();                                              // Idle time begins now
00609 
00610             break;
00611 
00612 
00613         default:                                                                            // This EDC_command is not handled, and considered an error
00614             LED_On(ET1200_AL_err_LED);                                                      // So light the red Application Layer LED.
00615             break;
00616     }
00617 }
00618 
00619 
00620 
00624 void Platform_Init_Callback(void)
00625 {
00626     unsigned char i;
00627 
00628     etherCAT_status_data.EDC_command         = 0xCC;//EDC_COMMAND_SENSOR_DATA;
00629     etherCAT_command_data.EDC_command        = 0xDD;//EDC_COMMAND_SENSOR_DATA;
00630     can_bridge_data_from_ROS.message_data[0] = 0xff;
00631 
00632     for (i = 1; i < ETHERCAT_STATUS_DATA_SIZE / 2 ; ++i)
00633         ((int16s *)&etherCAT_status_data)[i] = 0xDEAD;
00634     
00635     write_ET1200_register_N  ( ETHERCAT_STATUS_DATA_ADDRESS, ETHERCAT_STATUS_DATA_SIZE,   (int8u*)&etherCAT_status_data);
00636 }
00637 
00638 
00639 
00647 void report_error_code(ERROR_CODE  error_code)
00648 {
00649     switch (error_code)
00650     {
00651         case CAN1_TX_NO_BUFFER:
00652         case CAN1_TX_BUFFER_FULL:
00653         case CAN1_RX_BUFFER_FULL:
00654         case CAN1_BECOME_SAD:
00655         case SIMPLE_CAN_BAD_MESSAGE_BUS_1:          
00656             LED_Single_Flicker(LED_CAN1_ERR);
00657             break;
00658 
00659         case CAN2_TX_NO_BUFFER:
00660         case CAN2_TX_BUFFER_FULL:
00661         case CAN2_RX_BUFFER_FULL:
00662         case CAN2_BECOME_SAD:
00663         case SIMPLE_CAN_BAD_MESSAGE_BUS_2:
00664             LED_Single_Flicker(LED_CAN2_ERR);
00665             break;
00666 
00667         default:
00668             NYI();                                  // Otherwise, panic!
00669             break;
00670     }
00671 }
00672 
00673 
00674 
00682 void report_event_code   (EVENT_CODE  event_code)
00683 {
00684     switch (event_code)
00685     {
00686 /*
00687         case CAN1_RECEIVED_MESSAGE:         LED_Single_Flicker(LED_CAN1_RX);            break;
00688         case CAN1_TRANSMITTED_MESSAGE:      LED_Single_Flicker(LED_CAN1_TX);            break;
00689 
00690         #ifdef LED_CAN2_RX_PIN
00691             case CAN2_RECEIVED_MESSAGE:         LED_Single_Flicker(LED_CAN2_RX);            break;
00692         #endif
00693 
00694         case CAN2_TRANSMITTED_MESSAGE:      LED_Single_Flicker(LED_CAN2_TX);            break;
00695 */
00696 
00697         case CAN1_RECEIVED_MESSAGE:         LED_On_For_5ms(LED_CAN1_RX);            break;
00698         case CAN1_TRANSMITTED_MESSAGE:      LED_On_For_5ms(LED_CAN1_TX);            break;
00699 
00700         #ifdef LED_CAN2_RX_PIN
00701             case CAN2_RECEIVED_MESSAGE:         LED_On_For_5ms(LED_CAN2_RX);            break;
00702         #endif
00703 
00704         case CAN2_TRANSMITTED_MESSAGE:      LED_On_For_5ms(LED_CAN2_TX);            break;
00705 
00706         default:
00707             break;
00708     }
00709 }
00710 
00711 
00712 
00716 void report_error_string (char *error_string, ...)
00717 {
00718     
00719     assert_dynamic(0);                  // Protection while function is as yet unimplemented
00720     error_string = NULL;
00721 }
00722 
00723 
00724 
00728 void report_event_string (char *event_string, ...)
00729 {
00730     //assert_dynamic(0);                  // Protection while function is as yet unimplemented
00731     event_string = NULL; // to avoid warning
00732 }
00733 
00734 
00735 
00739 void __assert_dynamic_fail(const char* UNUSED(fmt), ...)
00740 {
00741     unsigned int i;
00742 
00743     TRISDCLR = 0b00000100111110001;
00744     PORTDCLR = 0b00000100111110001;
00745 
00746     while(1)
00747     {
00748         PORTDINV = 0b00000100111110001;
00749     
00750         for (i=0; i<1000000; i++)
00751         {
00752             Nop();
00753             Nop();
00754             Nop();
00755             Nop();
00756         }
00757     }    
00758 }
00759 
00760 
00761 
00771 void Received_Motor_Data(FROM_MOTOR_DATA_TYPE data_type, int8u motor_number, int16s measured_torque, int16u other_value)
00772 {
00773     if (motor_number > 19)                                                                              // A motor_number > 19 is an error
00774     {                                                                                                   // Let's just ignore it and hope it goes away.
00775         return;
00776     }
00777 
00778     FROM_MOTOR_DATA_TYPE    expected_data_type   = etherCAT_command_data.from_motor_data_type;
00779 
00780     num_motor_CAN_messages_received_this_frame++;
00781 
00782     if (data_type == expected_data_type)                                                                // This is good :)
00783     {
00784         etherCAT_status_data.motor_data_type                            = data_type;
00785         etherCAT_status_data.motor_data_packet[motor_number>>1].torque  = measured_torque;
00786         etherCAT_status_data.motor_data_packet[motor_number>>1].misc    = other_value;
00787 
00788         etherCAT_status_data.which_motor_data_arrived                  |= 0x00000001 << motor_number;   // Record that a message arrived
00789         etherCAT_status_data.which_motor_data_had_errors               &= 0xFFFFFFFE << motor_number;   // and that it was good (as far as we can tell)
00790     }
00791     else
00792     {
00793         etherCAT_status_data.which_motor_data_arrived                  |= 0x00000001 << motor_number;   // Record that a message arrived
00794         etherCAT_status_data.which_motor_data_had_errors               |= 0x00000001 << motor_number;   // and that it was bad :(
00795     }
00796 }
00797 
00798 
00799 
00805 void delay_us(int32u microseconds) 
00806 { 
00807     int32u start = ReadCoreTimer(); 
00808     int32u stop  = (microseconds-1) * (SYSTEM_FREQ_HZ/2000000);     // Subtract 1 to account for call overheads.
00809     
00810     stop += start;                                  //
00811     
00812     while (ReadCoreTimer() < stop)                  // wait till Count reaches the stop value
00813     {
00814     }
00815 }
00816 
00817 
00818 
00825 void delay_ms(int32u milliseconds)
00826 { 
00827     int32u start     = ReadCoreTimer(); 
00828     int32u num_ticks = milliseconds * (SYSTEM_FREQ_HZ/2000);
00829     
00830     while (ReadCoreTimer()-start < num_ticks)                  // wait till Count reaches the stop value
00831     {
00832     }
00833 } 
00834 
00835 


sr_external_dependencies
Author(s): Ugo Cupcic/ ugo@shadowrobot.com, software@shadowrobot.com
autogenerated on Thu Jan 2 2014 12:01:42