fp@0: /****************************************************************************** fp@0: * fp@0: * msr_io.c fp@0: * fp@0: * Sample Modul für EtherCAT fp@0: * fp@0: * Autoren: Wilhelm Hagemeister, Florian Pose fp@0: * fp@0: * $Date$ fp@0: * $Author$ fp@0: * fp@0: * (C) Copyright IgH 2005 fp@0: * Ingenieurgemeinschaft IgH fp@0: * Heinz-Bäcker Str. 34 fp@0: * D-45356 Essen fp@0: * Tel.: +49 201/61 99 31 fp@0: * Fax.: +49 201/61 98 36 fp@0: * E-mail: hm@igh-essen.com fp@0: * fp@0: * /bin/setserial /dev/ttyS0 uart none fp@0: * /bin/setserial /dev/ttyS1 uart none fp@0: * fp@0: ******************************************************************************/ fp@0: fp@0: /*--Includes-----------------------------------------------------------------*/ fp@0: fp@0: #include fp@0: #include fp@0: #include fp@0: #include fp@0: fp@0: #include fp@0: #include fp@0: #include fp@0: fp@0: #include fp@0: #include fp@0: fp@0: #include "msr_io.h" fp@0: fp@0: //#include fp@0: fp@0: #include "../drivers/ec_master.h" fp@0: #include "../drivers/ec_device.h" fp@0: #include "../drivers/ec_types.h" fp@0: #include "../rs232dbg/rs232dbg.h" fp@0: fp@0: /*--Defines------------------------------------------------------------------*/ fp@0: fp@0: #define TIMERTICS 1e6 // in ns; Thus have a task time of 1ms fp@0: #define MSR_ABTASTFREQUENZ (1e9/TIMERTICS) fp@0: fp@0: //#define MSR_ABTASTFREQUENZ (1000) //1e9/TIMERTICS) fp@0: #define TICK ((1000000 / MSR_ABTASTFREQUENZ) * 1000) fp@0: #define TIMER_FREQ (APIC_TIMER ? FREQ_APIC : FREQ_8254) fp@0: #define APIC_TIMER 0 fp@0: fp@0: //#define MSR_SLOW_DEBUG fp@0: fp@0: /*--Globale Variablen--------------------------------------------------------*/ fp@0: fp@0: RT_TASK process_image; fp@0: fp@0: const int Tick = TICK; fp@0: fp@0: unsigned int ecat_tx_delay = 0; //Zeit vom Ende der TimerInterruptRoutine bis fp@0: //TX-Interrupt der Netzwerkkarte fp@0: unsigned int ecat_rx_delay = 0; //RX-Interrupt der Netzwerkkarte fp@0: fp@0: unsigned int tx_intr = 0; fp@0: unsigned int rx_intr = 0; fp@0: unsigned int total_intr = 0; fp@0: fp@0: unsigned int thread_end = 0; fp@0: fp@0: #define USE_ETHERCAT fp@0: fp@0: #ifdef USE_ETHERCAT fp@0: fp@0: static EtherCAT_master_t *ecat_master = NULL; fp@0: fp@0: extern EtherCAT_device_t rtl_ecat_dev; fp@0: fp@0: //#define ECAT_SLAVES_COUNT 16 fp@0: fp@0: static EtherCAT_slave_t ecat_slaves[] = fp@0: { fp@0: //Block 1 hm@6: /* ECAT_INIT_SLAVE(Beckhoff_EK1100), fp@0: ECAT_INIT_SLAVE(Beckhoff_EL4102), fp@0: ECAT_INIT_SLAVE(Beckhoff_EL3162), fp@0: ECAT_INIT_SLAVE(Beckhoff_EL1014), fp@0: ECAT_INIT_SLAVE(Beckhoff_EL2004), fp@0: ECAT_INIT_SLAVE(Beckhoff_EL3102), fp@0: ECAT_INIT_SLAVE(Beckhoff_EL4102), fp@0: ECAT_INIT_SLAVE(Beckhoff_EL4102), fp@0: ECAT_INIT_SLAVE(Beckhoff_EL4102), fp@0: ECAT_INIT_SLAVE(Beckhoff_EL3162), fp@0: ECAT_INIT_SLAVE(Beckhoff_EL3162), fp@0: ECAT_INIT_SLAVE(Beckhoff_EL3162), fp@0: ECAT_INIT_SLAVE(Beckhoff_EL3102), fp@0: ECAT_INIT_SLAVE(Beckhoff_EL3102), fp@0: ECAT_INIT_SLAVE(Beckhoff_EL2004), fp@0: ECAT_INIT_SLAVE(Beckhoff_EL2004), fp@0: ECAT_INIT_SLAVE(Beckhoff_EL2004), hm@6: ECAT_INIT_SLAVE(Beckhoff_EL2004), */ fp@0: //Block 2 fp@0: ECAT_INIT_SLAVE(Beckhoff_EK1100), fp@0: ECAT_INIT_SLAVE(Beckhoff_EL4102), fp@0: ECAT_INIT_SLAVE(Beckhoff_EL1014), fp@0: ECAT_INIT_SLAVE(Beckhoff_EL3162), fp@0: ECAT_INIT_SLAVE(Beckhoff_EL2004), fp@0: ECAT_INIT_SLAVE(Beckhoff_EL3102), fp@0: //Block 3 fp@0: ECAT_INIT_SLAVE(Beckhoff_EK1100), fp@0: ECAT_INIT_SLAVE(Beckhoff_EL1014), fp@0: ECAT_INIT_SLAVE(Beckhoff_EL1014), fp@0: ECAT_INIT_SLAVE(Beckhoff_EL1014), fp@0: ECAT_INIT_SLAVE(Beckhoff_EL1014), fp@0: ECAT_INIT_SLAVE(Beckhoff_EL1014), fp@0: ECAT_INIT_SLAVE(Beckhoff_EL2004), fp@0: ECAT_INIT_SLAVE(Beckhoff_EL2004), fp@0: ECAT_INIT_SLAVE(Beckhoff_EL2004), fp@0: ECAT_INIT_SLAVE(Beckhoff_EL2004), fp@0: ECAT_INIT_SLAVE(Beckhoff_EL1014), fp@0: ECAT_INIT_SLAVE(Beckhoff_EL1014), fp@0: ECAT_INIT_SLAVE(Beckhoff_EL1014) fp@0: fp@0: fp@0: }; fp@0: fp@0: #define ECAT_SLAVES_COUNT (sizeof(ecat_slaves)/sizeof(EtherCAT_slave_t)) fp@0: fp@0: #endif fp@0: fp@0: double value; fp@0: int dig1; fp@0: fp@0: fp@0: static int next2004(int *wrap) fp@0: { fp@0: static int i=0; fp@0: fp@0: int j=0; fp@0: fp@0: *wrap = 0; fp@0: for(j=0;jdev->tx_time-k)) fp@0: / (current_cpu_data.loops_per_jiffy / 10); fp@0: ecat_rx_delay = ((unsigned int) (100000 / HZ) * (ecat_master->dev->rx_time-k)) fp@0: / (current_cpu_data.loops_per_jiffy / 10); fp@0: fp@0: rx_intr = ecat_master->dev->rx_intr_cnt; fp@0: tx_intr = ecat_master->dev->tx_intr_cnt; fp@0: total_intr = ecat_master->dev->intr_cnt; fp@0: // Prozessdaten lesen fp@0: if(!firstrun) { fp@0: EtherCAT_read_process_data(ecat_master); fp@0: fp@0: // Daten lesen und skalieren fp@0: value = EtherCAT_read_value(&ecat_master->slaves[5], 0) / 3276.7; fp@0: dig1 = EtherCAT_read_value(&ecat_master->slaves[3], 0); fp@0: } fp@0: // Daten schreiben fp@0: fp@0: EtherCAT_write_value(&ecat_master->slaves[4], 0, ms > 500 ? 1 : 0); fp@0: EtherCAT_write_value(&ecat_master->slaves[4], 1, ms > 500 ? 0 : 1); fp@0: EtherCAT_write_value(&ecat_master->slaves[4], 2, ms > 500 ? 0 : 1); fp@0: EtherCAT_write_value(&ecat_master->slaves[4], 3, ms > 500 ? 1 : 0); fp@0: fp@0: fp@0: if(cnt++ > 20) { fp@0: cnt = 0; fp@0: if(++kanal > 3) { fp@0: kanal = 0; fp@0: klemme = next2004(&wrap); fp@0: if (wrap == 1) { fp@0: if(up_down == 1) fp@0: up_down = 0; fp@0: else up_down = 1; fp@0: } fp@0: } fp@0: } fp@0: if (klemme >=0) fp@0: EtherCAT_write_value(&ecat_master->slaves[klemme], kanal,up_down); fp@0: fp@0: // EtherCAT_write_value(&ecat_master->slaves[13], 1, ms > 500 ? 0 : 1); fp@0: // EtherCAT_write_value(&ecat_master->slaves[14], 2, ms > 500 ? 0 : 1); fp@0: // EtherCAT_write_value(&ecat_master->slaves[15], 3, ms > 500 ? 1 : 0); fp@0: fp@0: // Prozessdaten schreiben fp@0: rdtscl(k); fp@0: EtherCAT_write_process_data(ecat_master); fp@0: firstrun = 0; fp@0: #endif fp@0: } fp@0: fp@0: /* fp@0: ******************************************************************************* fp@0: * fp@0: * Function: msr_run_interrupt fp@0: * fp@0: * Beschreibung: Interrupt abarbeiten fp@0: * fp@0: * Parameter: fp@0: * fp@0: * Rückgabe: fp@0: * fp@0: * Status: exp fp@0: * fp@0: ******************************************************************************* fp@0: */ fp@0: fp@0: void process_thread(int priv_data) fp@0: { fp@0: while (1) fp@0: { fp@0: fp@0: #ifdef USE_ETHERCAT fp@0: MSR_RTAITHREAD_CODE(msr_controller(); msr_write_kanal_list(); ); fp@0: #else fp@0: MSR_RTAITHREAD_CODE( msr_write_kanal_list(); ); fp@0: #endif fp@0: fp@0: fp@0: fp@0: /* if(counter++ >=MSR_ABTASTFREQUENZ) { fp@0: counter = 0; fp@0: sprintf(buf,"rt:life"); fp@0: msr_print_info(buf); fp@0: } fp@0: */ fp@0: rt_task_wait_period(); fp@0: } fp@0: thread_end = 1; fp@0: } fp@0: fp@0: /* fp@0: ******************************************************************************* fp@0: * fp@0: * Function: msr_register_channels fp@0: * fp@0: * Beschreibung: Kanäle registrieren fp@0: * fp@0: * Parameter: fp@0: * fp@0: * Rückgabe: fp@0: * fp@0: * Status: exp fp@0: * fp@0: ******************************************************************************* fp@0: */ fp@0: fp@0: int msr_globals_register(void) fp@0: { fp@0: msr_reg_kanal("/value", "V", &value, TDBL); fp@0: msr_reg_kanal("/dig1", "", &dig1, TINT); fp@0: msr_reg_kanal("/Taskinfo/Ecat/TX-Delay","us",&ecat_tx_delay,TUINT); fp@0: msr_reg_kanal("/Taskinfo/Ecat/RX-Delay","us",&ecat_rx_delay,TUINT); fp@0: msr_reg_kanal("/Taskinfo/Ecat/TX-Cnt","",&tx_intr,TUINT); fp@0: msr_reg_kanal("/Taskinfo/Ecat/RX-Cnt","",&rx_intr,TUINT); fp@0: msr_reg_kanal("/Taskinfo/Ecat/Total-Cnt","",&total_intr,TUINT); fp@0: fp@0: return 0; fp@0: } fp@0: fp@0: /* fp@0: ******************************************************************************* fp@0: * fp@0: * Function: msr_init fp@0: * fp@0: * Beschreibung: MSR initialisieren fp@0: * fp@0: * Parameter: fp@0: * fp@0: * Rückgabe: fp@0: * fp@0: * Status: exp fp@0: * fp@0: ******************************************************************************* fp@0: */ fp@0: fp@0: int msr_init(void) fp@0: { fp@0: int rv = -1; fp@0: RTIME tick_period, now; fp@0: fp@0: // rt_mount_rtai(); fp@0: fp@0: msr_print_info("Initialising rtlib."); fp@0: fp@0: // RT-lib initialisieren fp@0: if (msr_rtlib_init(1, MSR_ABTASTFREQUENZ, 10, msr_globals_register) < 0) fp@0: { fp@0: msr_print_warn("msr_modul: can't initialize rtlib!"); fp@0: goto out_umount; fp@0: } fp@0: fp@0: #ifdef USE_ETHERCAT fp@0: msr_print_info("Opening EtherCAT device."); fp@0: fp@0: mdelay(100); fp@0: fp@0: if (EtherCAT_device_open(&rtl_ecat_dev) < 0) fp@0: { fp@0: msr_print_warn("msr_modul: Could not initialize EtherCAT NIC."); fp@0: goto out_rtlib; fp@0: } fp@0: fp@0: if (!rtl_ecat_dev.dev) // Es gibt kein EtherCAT-Device fp@0: { fp@0: msr_print_warn("msr_modul: No EtherCAT device!"); fp@0: goto out_close; fp@0: } fp@0: // goto out_close; fp@0: fp@0: // EtherCAT-Master und Slaves initialisieren fp@0: fp@0: msr_print_info("Initialising EtherCAT master"); fp@0: fp@0: if ((ecat_master = (EtherCAT_master_t *) kmalloc(sizeof(EtherCAT_master_t), GFP_KERNEL)) == 0) fp@0: { fp@0: msr_print_warn(KERN_ERR "msr_modul: Could not alloc memory for EtherCAT master!\n"); fp@0: goto out_close; fp@0: } fp@0: fp@0: if (EtherCAT_master_init(ecat_master, &rtl_ecat_dev) < 0) fp@0: { fp@0: msr_print_warn(KERN_ERR "EtherCAT could not init master!\n"); fp@0: goto out_master; fp@0: } fp@0: fp@0: msr_print_info("Checking EtherCAT slaves."); fp@0: mdelay(10); //Nachricht abwarten fp@0: fp@0: if (EtherCAT_check_slaves(ecat_master, ecat_slaves, ECAT_SLAVES_COUNT) != 0) fp@0: { fp@0: msr_print_warn(KERN_ERR "EtherCAT: Could not init slaves!\n"); fp@0: goto out_masterclear; fp@0: } fp@0: fp@0: msr_print_info("Activating all EtherCAT slaves."); fp@0: mdelay(10); //Nachricht abwarten fp@0: fp@0: if (EtherCAT_activate_all_slaves(ecat_master) != 0) fp@0: { fp@0: printk(KERN_ERR "EtherCAT: Could not activate slaves!\n"); fp@0: goto out_masterclear; fp@0: } fp@0: fp@0: // Zyklischen Aufruf starten fp@0: fp@0: #endif fp@0: msr_print_info("Starting cyclic sample thread."); fp@0: mdelay(10); //Nachricht abwarten fp@0: fp@0: EtherCAT_write_process_data(ecat_master); fp@0: fp@0: //mdelay(100); fp@0: tick_period = start_rt_timer(nano2count(TIMERTICS)); fp@0: now = rt_get_time(); fp@0: fp@0: if ((rv = rt_task_init(&process_image, process_thread, 0/*data*/, 64000/*stacksize*/, 0/*prio*/, 1/*use fpu*/, 0/*signal*/))) fp@0: { fp@0: msr_print_error("Could not initialise process_thread\n"); fp@0: goto out_stoptimer; fp@0: } fp@0: fp@0: msr_print_info("Initialised sample thread\n"); fp@0: fp@0: if ((rv = rt_task_make_periodic(&process_image, fp@0: now + tick_period, fp@0: tick_period))) fp@0: { fp@0: msr_print_error("Could not start process_thread\n"); fp@0: goto out_stoptask; fp@0: } fp@0: fp@0: msr_print_info("Started sample thread."); fp@0: fp@0: return 0; fp@0: fp@0: out_stoptask: fp@0: msr_print_info("Deleting task...."); fp@0: rt_task_delete(&process_image); fp@0: fp@0: out_stoptimer: fp@0: msr_print_info("Stopping timer."); fp@0: stop_rt_timer(); fp@0: fp@0: #ifdef USE_ETHERCAT fp@0: out_masterclear: fp@0: msr_print_info("Clearing EtherCAT master."); fp@0: EtherCAT_master_clear(ecat_master); fp@0: fp@0: out_master: fp@0: msr_print_info("Freeing EtherCAT master."); fp@0: kfree(ecat_master); fp@0: fp@0: out_close: fp@0: msr_print_info("Closing device."); fp@0: fp@0: EtherCAT_device_close(&rtl_ecat_dev); fp@0: #endif fp@0: fp@0: out_rtlib: fp@0: msr_print_info("msr_rtlib_cleanup()"); fp@0: mdelay(10); fp@0: msr_rtlib_cleanup(); fp@0: fp@0: out_umount: fp@0: // rt_umount_rtai(); fp@0: fp@0: return rv; fp@0: } fp@0: fp@0: /* fp@0: ******************************************************************************* fp@0: * fp@0: * Function: msr_io_cleanup fp@0: * fp@0: * Beschreibung: Aufräumen fp@0: * fp@0: * Parameter: fp@0: * fp@0: * Rückgabe: fp@0: * fp@0: * Status: exp fp@0: * fp@0: ******************************************************************************* fp@0: */ fp@0: fp@0: void msr_io_cleanup(void) fp@0: { fp@0: fp@0: msr_print_info("Stopping timer."); fp@0: fp@0: stop_rt_timer(); fp@0: fp@0: msr_print_info("Deleting task...."); fp@0: fp@0: rt_task_delete(&process_image); fp@0: /* fp@0: for(i=0;i<1000;i++) { fp@0: udelay(100); fp@0: if(thread_end == 1) { fp@0: msr_print_info("Task ended at count %d",i); fp@0: break; fp@0: } fp@0: } fp@0: */ fp@0: //noch einmal lesen fp@0: fp@0: msr_print_info("Read Processdata"); fp@0: EtherCAT_read_process_data(ecat_master); fp@0: fp@0: //EtherCAT_read_process_data(ecat_master); fp@0: #ifdef USE_ETHERCAT fp@0: if (ecat_master) fp@0: { fp@0: fp@0: msr_print_info("Deactivating slaves."); fp@0: fp@0: fp@0: EtherCAT_deactivate_all_slaves(ecat_master); fp@0: fp@0: fp@0: msr_print_info("Clearing EtherCAT master."); fp@0: fp@0: EtherCAT_master_clear(ecat_master); fp@0: fp@0: msr_print_info("Freeing EtherCAT master."); fp@0: fp@0: fp@0: kfree(ecat_master); fp@0: ecat_master = NULL; fp@0: } fp@0: fp@0: msr_print_info("Closing device."); fp@0: fp@0: EtherCAT_device_close(&rtl_ecat_dev); fp@0: fp@0: #endif fp@0: msr_print_info("msr_rtlib_cleanup()"); fp@0: fp@0: msr_rtlib_cleanup(); fp@0: //rt_umount_rtai(); fp@0: } fp@0: fp@0: /*---Treiber-Einsprungspunkte etc.-------------------------------------------*/ fp@0: fp@0: MODULE_LICENSE("GPL"); fp@0: fp@0: module_init(msr_init); fp@0: module_exit(msr_io_cleanup); fp@0: fp@0: /*---Ende--------------------------------------------------------------------*/