From dc11bdd460e9de18bd688de695c4df7cb6358c09 Mon Sep 17 00:00:00 2001 From: Hans-Erik Floryd Date: Thu, 19 Jun 2025 14:49:06 +0200 Subject: [PATCH] Delete obsolete or duplicate tests Portable sample code is now in the sample folder. Change-Id: I6d9315c92152ca4321bec325f78e64849e6b1e47 --- test/linux/ebox/ebox.c | 396 ---------------- test/rtk/main.c | 510 --------------------- test/rtk/schedule.tt | 14 - test/win32/ebox/ebox.c | 398 ---------------- test/win32/eepromtool/eepromtool.c | 389 ---------------- test/win32/firm_update/firm_update.c | 156 ------- test/win32/red_test/red_test.c | 265 ----------- test/win32/simple_test/simple_test.c | 372 --------------- test/win32/slaveinfo/slaveinfo.c | 658 --------------------------- 9 files changed, 3158 deletions(-) delete mode 100644 test/linux/ebox/ebox.c delete mode 100644 test/rtk/main.c delete mode 100644 test/rtk/schedule.tt delete mode 100644 test/win32/ebox/ebox.c delete mode 100644 test/win32/eepromtool/eepromtool.c delete mode 100644 test/win32/firm_update/firm_update.c delete mode 100644 test/win32/red_test/red_test.c delete mode 100644 test/win32/simple_test/simple_test.c delete mode 100644 test/win32/slaveinfo/slaveinfo.c diff --git a/test/linux/ebox/ebox.c b/test/linux/ebox/ebox.c deleted file mode 100644 index 1d2aebd..0000000 --- a/test/linux/ebox/ebox.c +++ /dev/null @@ -1,396 +0,0 @@ -/** \file - * \brief Example code for Simple Open EtherCAT master - * - * Usage : ebox [ifname] [cycletime] - * ifname is NIC interface, f.e. eth0 - * cycletime in us, f.e. 500 - * - * This test is specifically build for the E/BOX. - * - * (c)Arthur Ketels 2011 - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ethercat.h" - -#define NSEC_PER_SEC 1000000000 - -typedef struct PACKED -{ - uint8 status; - uint8 counter; - uint8 din; - int32 ain[2]; - uint32 tsain; - int32 enc[2]; -} in_EBOXt; - -typedef struct PACKED -{ - uint8 counter; - int16 stream[100]; -} in_EBOX_streamt; - -typedef struct PACKED -{ - uint8 control; - uint8 dout; - int16 aout[2]; - uint16 pwmout[2]; -} out_EBOXt; - -typedef struct PACKED -{ - uint8 control; -} out_EBOX_streamt; - -// total samples to capture -#define MAXSTREAM 200000 -// sample interval in ns, here 8us -> 125kHz -// maximum data rate for E/BOX v1.0.1 is around 150kHz -#define SYNC0TIME 8000 - -struct sched_param schedp; -char IOmap[4096]; -pthread_t thread1; -struct timeval tv, t1, t2; -int dorun = 0; -int deltat, tmax = 0; -int64 toff; -int DCdiff; -int os; -uint32 ob; -int16 ob2; -uint8 ob3; -pthread_cond_t cond = PTHREAD_COND_INITIALIZER; -pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; -int64 integral = 0; -uint32 cyclecount; -in_EBOX_streamt *in_EBOX; -out_EBOX_streamt *out_EBOX; -double ain[2]; -int ainc; -int streampos; -int16 stream1[MAXSTREAM]; -int16 stream2[MAXSTREAM]; - -int output_cvs(char *fname, int length) -{ - FILE *fp; - - int i; - - fp = fopen(fname, "w"); - if (fp == NULL) - return 0; - for (i = 0; i < length; i++) - { - fprintf(fp, "%d %d %d\n", i, stream1[i], stream2[i]); - } - fclose(fp); - - return 1; -} - -void eboxtest(char *ifname) -{ - int cnt, i; - - printf("Starting E/BOX test\n"); - - /* initialise SOEM, bind socket to ifname */ - if (ec_init(ifname)) - { - printf("ec_init on %s succeeded.\n", ifname); - /* find and auto-config slaves */ - if (ec_config_init(FALSE) > 0) - { - printf("%d slaves found and configured.\n", ec_slavecount); - - // check if first slave is an E/BOX - if ((ec_slavecount >= 1) && - (strcmp(ec_slave[1].name, "E/BOX") == 0)) - { - // reprogram PDO mapping to set slave in stream mode - // this can only be done in pre-OP state - os = sizeof(ob2); - ob2 = 0x1601; - ec_SDOwrite(1, 0x1c12, 01, FALSE, os, &ob2, EC_TIMEOUTRXM); - os = sizeof(ob2); - ob2 = 0x1a01; - ec_SDOwrite(1, 0x1c13, 01, FALSE, os, &ob2, EC_TIMEOUTRXM); - } - - ec_config_map(&IOmap); - - ec_configdc(); - - /* wait for all slaves to reach SAFE_OP state */ - ec_statecheck(0, EC_STATE_SAFE_OP, EC_TIMEOUTSTATE); - - /* configure DC options for every DC capable slave found in the list */ - printf("DC capable : %d\n", ec_configdc()); - - /* check configuration */ - if ((ec_slavecount >= 1) && - (strcmp(ec_slave[1].name, "E/BOX") == 0)) - { - printf("E/BOX found.\n"); - - /* connect struct pointers to slave I/O pointers */ - in_EBOX = (in_EBOX_streamt *)ec_slave[1].inputs; - out_EBOX = (out_EBOX_streamt *)ec_slave[1].outputs; - - /* read indevidual slave state and store in ec_slave[] */ - ec_readstate(); - for (cnt = 1; cnt <= ec_slavecount; cnt++) - { - printf("Slave:%d Name:%s Output size:%3dbits Input size:%3dbits State:%2d delay:%d.%d\n", - cnt, ec_slave[cnt].name, ec_slave[cnt].Obits, ec_slave[cnt].Ibits, - ec_slave[cnt].state, (int)ec_slave[cnt].pdelay, ec_slave[cnt].hasdc); - } - printf("Request operational state for all slaves\n"); - - /* send one processdata cycle to init SM in slaves */ - ec_send_processdata(); - ec_receive_processdata(EC_TIMEOUTRET); - - ec_slave[0].state = EC_STATE_OPERATIONAL; - /* request OP state for all slaves */ - ec_writestate(0); - /* wait for all slaves to reach OP state */ - ec_statecheck(0, EC_STATE_OPERATIONAL, EC_TIMEOUTSTATE); - if (ec_slave[0].state == EC_STATE_OPERATIONAL) - { - printf("Operational state reached for all slaves.\n"); - ain[0] = 0; - ain[1] = 0; - ainc = 0; - dorun = 1; - usleep(100000); // wait for linux to sync on DC - ec_dcsync0(1, TRUE, SYNC0TIME, 0); // SYNC0 on slave 1 - /* acyclic loop 20ms */ - for (i = 1; i <= 200; i++) - { - /* read DC difference register for slave 2 */ - // ec_FPRD(ec_slave[1].configadr, ECT_REG_DCSYSDIFF, sizeof(DCdiff), &DCdiff, EC_TIMEOUTRET); - // if(DCdiff<0) { DCdiff = - (int32)((uint32)DCdiff & 0x7ffffff); } - printf("PD cycle %5d DCtime %12lld Cnt:%3d Data: %6d %6d %6d %6d %6d %6d %6d %6d \n", - cyclecount, ec_DCtime, in_EBOX->counter, in_EBOX->stream[0], in_EBOX->stream[1], - in_EBOX->stream[2], in_EBOX->stream[3], in_EBOX->stream[4], in_EBOX->stream[5], - in_EBOX->stream[98], in_EBOX->stream[99]); - usleep(20000); - } - dorun = 0; - // printf("\nCnt %d : Ain0 = %f Ain2 = %f\n", ainc, ain[0] / ainc, ain[1] / ainc); - } - else - { - printf("Not all slaves reached operational state.\n"); - } - } - else - { - printf("E/BOX not found in slave configuration.\n"); - } - ec_dcsync0(1, FALSE, 8000, 0); // SYNC0 off - printf("Request safe operational state for all slaves\n"); - ec_slave[0].state = EC_STATE_SAFE_OP; - /* request SAFE_OP state for all slaves */ - ec_writestate(0); - /* wait for all slaves to reach state */ - ec_statecheck(0, EC_STATE_SAFE_OP, EC_TIMEOUTSTATE); - ec_slave[0].state = EC_STATE_PRE_OP; - /* request SAFE_OP state for all slaves */ - ec_writestate(0); - /* wait for all slaves to reach state */ - ec_statecheck(0, EC_STATE_PRE_OP, EC_TIMEOUTSTATE); - if ((ec_slavecount >= 1) && - (strcmp(ec_slave[1].name, "E/BOX") == 0)) - { - // restore PDO to standard mode - // this can only be done is pre-op state - os = sizeof(ob2); - ob2 = 0x1600; - ec_SDOwrite(1, 0x1c12, 01, FALSE, os, &ob2, EC_TIMEOUTRXM); - os = sizeof(ob2); - ob2 = 0x1a00; - ec_SDOwrite(1, 0x1c13, 01, FALSE, os, &ob2, EC_TIMEOUTRXM); - } - printf("Streampos %d\n", streampos); - output_cvs("stream.txt", streampos); - } - else - { - printf("No slaves found!\n"); - } - printf("End E/BOX, close socket\n"); - /* stop SOEM, close socket */ - ec_close(); - } - else - { - printf("No socket connection on %s\nExcecute as root\n", ifname); - } -} - -/* add ns to timespec */ -void add_timespec(struct timespec *ts, int64 addtime) -{ - int64 sec, nsec; - - nsec = addtime % NSEC_PER_SEC; - sec = (addtime - nsec) / NSEC_PER_SEC; - ts->tv_sec += sec; - ts->tv_nsec += nsec; - if (ts->tv_nsec >= NSEC_PER_SEC) - { - nsec = ts->tv_nsec % NSEC_PER_SEC; - ts->tv_sec += (ts->tv_nsec - nsec) / NSEC_PER_SEC; - ts->tv_nsec = nsec; - } -} - -/* PI calculation to get linux time synced to DC time */ -void ec_sync(int64 reftime, int64 cycletime, int64 *offsettime) -{ - int64 delta; - /* set linux sync point 50us later than DC sync, just as example */ - delta = (reftime - 50000) % cycletime; - if (delta > (cycletime / 2)) - { - delta = delta - cycletime; - } - if (delta > 0) - { - integral++; - } - if (delta < 0) - { - integral--; - } - *offsettime = -(delta / 100) - (integral / 20); -} - -/* RT EtherCAT thread */ -void ecatthread(void *ptr) -{ - struct timespec ts; - struct timeval tp; - int ht; - int i; - int pcounter = 0; - int64 cycletime; - - pthread_mutex_lock(&mutex); - gettimeofday(&tp, NULL); - - /* Convert from timeval to timespec */ - ts.tv_sec = tp.tv_sec; - ht = (tp.tv_usec / 1000) + 1; /* round to nearest ms */ - ts.tv_nsec = ht * 1000000; - cycletime = *(int *)ptr * 1000; /* cycletime in ns */ - toff = 0; - dorun = 0; - while (1) - { - /* calculate next cycle start */ - add_timespec(&ts, cycletime + toff); - /* wait to cycle start */ - pthread_cond_timedwait(&cond, &mutex, &ts); - if (dorun > 0) - { - gettimeofday(&tp, NULL); - - ec_send_processdata(); - - ec_receive_processdata(EC_TIMEOUTRET); - - cyclecount++; - - if ((in_EBOX->counter != pcounter) && (streampos < (MAXSTREAM - 1))) - { - // check if we have timing problems in master - // if so, overwrite stream data so it shows up clearly in plots. - if (in_EBOX->counter > (pcounter + 1)) - { - for (i = 0; i < 50; i++) - { - stream1[streampos] = 20000; - stream2[streampos++] = -20000; - } - } - else - { - for (i = 0; i < 50; i++) - { - stream1[streampos] = in_EBOX->stream[i * 2]; - stream2[streampos++] = in_EBOX->stream[(i * 2) + 1]; - } - } - pcounter = in_EBOX->counter; - } - - /* calulate toff to get linux time and DC synced */ - ec_sync(ec_DCtime, cycletime, &toff); - } - } -} - -int main(int argc, char *argv[]) -{ - int ctime; - struct sched_param param; - int policy = SCHED_OTHER; - - printf("SOEM (Simple Open EtherCAT Master)\nE/BOX test\n"); - - memset(&schedp, 0, sizeof(schedp)); - /* do not set priority above 49, otherwise sockets are starved */ - schedp.sched_priority = 30; - sched_setscheduler(0, SCHED_FIFO, &schedp); - - do - { - usleep(1000); - } while (dorun); - - if (argc > 1) - { - dorun = 1; - if (argc > 2) - ctime = atoi(argv[2]); - else - ctime = 1000; // 1ms cycle time - /* create RT thread */ - pthread_create(&thread1, NULL, (void *)&ecatthread, (void *)&ctime); - memset(¶m, 0, sizeof(param)); - /* give it higher priority */ - param.sched_priority = 40; - pthread_setschedparam(thread1, policy, ¶m); - - /* start acyclic part */ - eboxtest(argv[1]); - } - else - { - printf("Usage: ebox ifname [cycletime]\nifname = eth0 for example\ncycletime in us\n"); - } - - schedp.sched_priority = 0; - sched_setscheduler(0, SCHED_OTHER, &schedp); - - printf("End program\n"); - - return (0); -} diff --git a/test/rtk/main.c b/test/rtk/main.c deleted file mode 100644 index ebe810d..0000000 --- a/test/rtk/main.c +++ /dev/null @@ -1,510 +0,0 @@ -/** \file - * \brief Example code for Simple Open EtherCAT master - * - * This is a minimal example running rt-kernel TTOS. Check - * tutorial files in documentations for som steps to get your - * system running. - * (c)Andreas Karlsson 2012 - */ - -#include -#include "ethercat.h" -#include "string.h" -#include -#include - -#include - -#define pPORTFIO_SET ((vuint16_t *)PORTFIO_SET) -#define pPORTFIO_CLEAR ((vuint16_t *)PORTFIO_CLEAR) -#define pPORTFIO_DIR ((vuint16_t *)PORTFIO_DIR) - -#define EK1100_1 1 -#define EL4001_1 2 -#define EL3061_1 3 -#define EL1008_1 4 -#define EL1008_2 5 -#define EL2622_1 6 -#define EL2622_2 7 -#define EL2622_3 8 -#define EL2622_4 9 -#define NUMBER_OF_SLAVES 9 - -typedef struct -{ - uint8 in1; - uint8 in2; - uint8 in3; - uint8 in4; - uint8 in5; - uint8 in6; - uint8 in7; - uint8 in8; -} in_EL1008_t; - -typedef struct -{ - uint8 out1; - uint8 out2; -} out_EL2622_t; - -typedef struct -{ - int16 out1; -} out_EL4001_t; - -typedef struct -{ - int32 in1; -} in_EL3061_t; - -out_EL4001_t slave_EL4001_1; -in_EL3061_t slave_EL3061_1; -in_EL1008_t slave_EL1008_1; -in_EL1008_t slave_EL1008_2; -out_EL2622_t slave_EL2622_1; -out_EL2622_t slave_EL2622_2; -out_EL2622_t slave_EL2622_3; - -uint32 network_configuration(void) -{ - /* Do we got expected number of slaves from config */ - if (ec_slavecount < NUMBER_OF_SLAVES) - return 0; - - /* Verify slave by slave that it is correct*/ - if (strcmp(ec_slave[EK1100_1].name, "EK1100")) - return 0; - else if (strcmp(ec_slave[EL4001_1].name, "EL4001")) - return 0; - else if (strcmp(ec_slave[EL3061_1].name, "EL3061")) - return 0; - else if (strcmp(ec_slave[EL1008_1].name, "EL1008")) - return 0; - else if (strcmp(ec_slave[EL1008_2].name, "EL1008")) - return 0; - else if (strcmp(ec_slave[EL2622_1].name, "EL2622")) - return 0; - else if (strcmp(ec_slave[EL2622_2].name, "EL2622")) - return 0; - else if (strcmp(ec_slave[EL2622_3].name, "EL2622")) - return 0; - else if (strcmp(ec_slave[EL2622_4].name, "EL2622")) - return 0; - - return 1; -} - -int32 get_input_int32(uint16 slave_no, uint8 module_index) -{ - int32 return_value; - uint8 *data_ptr; - /* Get the IO map pointer from the ec_slave struct */ - data_ptr = ec_slave[slave_no].inputs; - /* Move pointer to correct module index */ - data_ptr += module_index * 4; - /* Read value byte by byte since all targets can't handle misaligned - * addresses - */ - return_value = *data_ptr++; - return_value += (*data_ptr++ << 8); - return_value += (*data_ptr++ << 16); - return_value += (*data_ptr++ << 24); - - return return_value; -} - -void set_input_int32(uint16 slave_no, uint8 module_index, int32 value) -{ - uint8 *data_ptr; - /* Get the IO map pointer from the ec_slave struct */ - data_ptr = ec_slave[slave_no].inputs; - /* Move pointer to correct module index */ - data_ptr += module_index * 4; - /* Read value byte by byte since all targets can handle misaligned - * addresses - */ - *data_ptr++ = (value >> 0) & 0xFF; - *data_ptr++ = (value >> 8) & 0xFF; - *data_ptr++ = (value >> 16) & 0xFF; - *data_ptr++ = (value >> 24) & 0xFF; -} - -uint8 get_input_bit(uint16 slave_no, uint8 module_index) -{ - /* Get the the startbit position in slaves IO byte */ - uint8 startbit = ec_slave[slave_no].Istartbit; - /* Mask bit and return boolean 0 or 1 */ - if (*ec_slave[slave_no].inputs & BIT(module_index - 1 + startbit)) - return 1; - else - return 0; -} - -int16 get_output_int16(uint16 slave_no, uint8 module_index) -{ - int16 return_value; - uint8 *data_ptr; - - /* Get the IO map pointer from the ec_slave struct */ - data_ptr = ec_slave[slave_no].outputs; - /* Move pointer to correct module index */ - data_ptr += module_index * 2; - /* Read value byte by byte since all targets can handle misaligned - * addresses - */ - return_value = *data_ptr++; - return_value += (*data_ptr++ << 8); - - return return_value; -} - -void set_output_int16(uint16 slave_no, uint8 module_index, int16 value) -{ - uint8 *data_ptr; - /* Get the IO map pointer from the ec_slave struct */ - data_ptr = ec_slave[slave_no].outputs; - /* Move pointer to correct module index */ - data_ptr += module_index * 2; - /* Read value byte by byte since all targets can handle misaligned - * addresses - */ - *data_ptr++ = (value >> 0) & 0xFF; - *data_ptr++ = (value >> 8) & 0xFF; -} - -uint8 get_output_bit(uint16 slave_no, uint8 module_index) -{ - /* Get the the startbit position in slaves IO byte */ - uint8 startbit = ec_slave[slave_no].Ostartbit; - /* Mask bit and return boolean 0 or 1 */ - if (*ec_slave[slave_no].outputs & BIT(module_index - 1 + startbit)) - return 1; - else - return 0; -} - -void set_output_bit(uint16 slave_no, uint8 module_index, uint8 value) -{ - /* Get the the startbit position in slaves IO byte */ - uint8 startbit = ec_slave[slave_no].Ostartbit; - /* Set or Clear bit */ - if (value == 0) - *ec_slave[slave_no].outputs &= ~(1 << (module_index - 1 + startbit)); - else - *ec_slave[slave_no].outputs |= (1 << (module_index - 1 + startbit)); -} - -extern tt_sched_t *tt_sched[]; - -char IOmap[128]; -int dorun = 0; - -uint8_t load1s, load5s, load10s; -uint32_t error_counter = 0; - -void tt_error(uint32_t task_ix); -void tt_error(uint32_t task_ix) -{ - error_counter++; -} - -static void my_cyclic_callback(void *arg) -{ - while (1) - { - stats_get_load(&load1s, &load5s, &load10s); - rprintp("Processor load was %d:%d:%d (1s:5s:10s) with TT errors: %d\n", - load1s, load5s, load10s, error_counter); - task_delay(20000); - } -} - -void read_io(void *arg) -{ - /* Function connected to cyclic TTOS task - * The function is executed cyclic according - * sceduel specified in schedule.tt - */ - *pPORTFIO_SET = BIT(6); - /* Send and receive processdata - * Note that you need som synchronization - * case you modifey IO in local application - */ - ec_send_processdata(); - ec_receive_processdata(EC_TIMEOUTRET); - *pPORTFIO_CLEAR = BIT(6); -} - -void simpletest(void *arg) -{ - - char *ifname = arg; - int cnt, i, j; - - *pPORTFIO_DIR |= BIT(6); - - rprintp("Starting simple test\n"); - - /* initialise SOEM */ - if (ec_init(ifname)) - { - rprintp("ec_init succeeded.\n"); - - /* find and auto-config slaves */ - if (ec_config_init(FALSE) > 0) - { - rprintp("%d slaves found and configured.\n", ec_slavecount); - - /* Check network setup */ - if (network_configuration()) - { - /* Run IO mapping */ - ec_config_map(&IOmap); - - rprintp("Slaves mapped, state to SAFE_OP.\n"); - /* wait for all slaves to reach SAFE_OP state */ - ec_statecheck(0, EC_STATE_SAFE_OP, EC_TIMEOUTSTATE); - - /* Print som information on the mapped network */ - for (cnt = 1; cnt <= ec_slavecount; cnt++) - { - rprintp("\nSlave:%d\n Name:%s\n Output size: %dbits\n Input size: %dbits\n State: %d\n Delay: %d[ns]\n Has DC: %d\n", - cnt, ec_slave[cnt].name, ec_slave[cnt].Obits, ec_slave[cnt].Ibits, - ec_slave[cnt].state, ec_slave[cnt].pdelay, ec_slave[cnt].hasdc); - rprintp(" Configured address: %x\n", ec_slave[cnt].configadr); - rprintp(" Outputs address: %x\n", ec_slave[cnt].outputs); - rprintp(" Inputs address: %x\n", ec_slave[cnt].inputs); - - for (j = 0; j < ec_slave[cnt].FMMUunused; j++) - { - rprintp(" FMMU%1d Ls:%x Ll:%4d Lsb:%d Leb:%d Ps:%x Psb:%d Ty:%x Act:%x\n", j, - (int)ec_slave[cnt].FMMU[j].LogStart, ec_slave[cnt].FMMU[j].LogLength, ec_slave[cnt].FMMU[j].LogStartbit, - ec_slave[cnt].FMMU[j].LogEndbit, ec_slave[cnt].FMMU[j].PhysStart, ec_slave[cnt].FMMU[j].PhysStartBit, - ec_slave[cnt].FMMU[j].FMMUtype, ec_slave[cnt].FMMU[j].FMMUactive); - } - rprintp(" FMMUfunc 0:%d 1:%d 2:%d 3:%d\n", - ec_slave[cnt].FMMU0func, ec_slave[cnt].FMMU1func, ec_slave[cnt].FMMU2func, ec_slave[cnt].FMMU3func); - } - - rprintp("Request operational state for all slaves\n"); - ec_slave[0].state = EC_STATE_OPERATIONAL; - /* send one valid process data to make outputs in slaves happy*/ - ec_send_processdata(); - ec_receive_processdata(EC_TIMEOUTRET); - /* request OP state for all slaves */ - ec_writestate(0); - /* wait for all slaves to reach OP state */ - ec_statecheck(0, EC_STATE_OPERATIONAL, EC_TIMEOUTSTATE); - if (ec_slave[0].state == EC_STATE_OPERATIONAL) - { - rprintp("Operational state reached for all slaves.\n"); - } - else - { - rprintp("Not all slaves reached operational state.\n"); - ec_readstate(); - for (i = 1; i <= ec_slavecount; i++) - { - if (ec_slave[i].state != EC_STATE_OPERATIONAL) - { - rprintp("Slave %d State=0x%04x StatusCode=0x%04x\n", - i, ec_slave[i].state, ec_slave[i].ALstatuscode); - } - } - } - - /* Simple blinking lamps BOX demo */ - uint8 digout = 0; - - slave_EL4001_1.out1 = (int16)0x3FFF; - set_output_int16(EL4001_1, 0, slave_EL4001_1.out1); - - task_spawn("t_StatsPrint", my_cyclic_callback, 20, 1024, (void *)NULL); - tt_start_wait(tt_sched[0]); - - while (1) - { - dorun = 0; - slave_EL1008_1.in1 = get_input_bit(EL1008_1, 1); // Start button - slave_EL1008_1.in2 = get_input_bit(EL1008_1, 2); // Turnkey RIGHT - slave_EL1008_1.in3 = get_input_bit(EL1008_1, 3); // Turnkey LEFT - - /* (Turnkey MIDDLE + Start button) OR Turnkey RIGHT OR Turnkey LEFT - Turnkey LEFT: Light positions bottom to top. Loop, slow operation. - Turnkey MIDDLE: Press start button to light positions bottom to top. No loop, fast operation. - Turnkey RIGHT: Light positions bottom to top. Loop, fast operation. - */ - if (slave_EL1008_1.in1 || slave_EL1008_1.in2 || slave_EL1008_1.in3) - { - digout = 0; - /* *ec_slave[6].outputs = digout; */ - /* set_output_bit(slave_name #,index as 1 output on module , value */ - set_output_bit(EL2622_1, 1, (digout & BIT(0))); /* Start button */ - set_output_bit(EL2622_1, 2, (digout & BIT(1))); /* Turnkey RIGHT */ - set_output_bit(EL2622_2, 1, (digout & BIT(2))); /* Turnkey LEFT */ - set_output_bit(EL2622_2, 2, (digout & BIT(3))); - set_output_bit(EL2622_3, 1, (digout & BIT(4))); - set_output_bit(EL2622_3, 2, (digout & BIT(5))); - - while (dorun < 95) - { - dorun++; - - if (slave_EL1008_1.in3) - task_delay(tick_from_ms(20)); - else - task_delay(tick_from_ms(5)); - - digout = (uint8)(digout | BIT((dorun / 16) & 0xFF)); - - set_output_bit(EL2622_1, 1, (digout & BIT(0))); /* LED1 */ - set_output_bit(EL2622_1, 2, (digout & BIT(1))); /* LED2 */ - set_output_bit(EL2622_2, 1, (digout & BIT(2))); /* LED3 */ - set_output_bit(EL2622_2, 2, (digout & BIT(3))); /* LED4 */ - set_output_bit(EL2622_3, 1, (digout & BIT(4))); /* LED5 */ - set_output_bit(EL2622_3, 2, (digout & BIT(5))); /* LED6 */ - - slave_EL1008_1.in1 = get_input_bit(EL1008_1, 2); /* Turnkey RIGHT */ - slave_EL1008_1.in2 = get_input_bit(EL1008_1, 3); /* Turnkey LEFT */ - slave_EL3061_1.in1 = get_input_int32(EL3061_1, 0); /* Read AI */ - } - } - task_delay(tick_from_ms(2)); - } - } - else - { - rprintp("Mismatch of network units!\n"); - } - } - else - { - rprintp("No slaves found!\n"); - } - rprintp("End simple test, close socket\n"); - /* stop SOEM, close socket */ - ec_close(); - } - else - { - rprintp("ec_init failed"); - } - rprintp("End program\n"); -} - -static void test_osal_timer_timeout_us(const uint32 timeout_us) -{ - osal_timert timer; - - ASSERT(timeout_us > 4000); - - osal_timer_start(&timer, timeout_us); - ASSERT(osal_timer_is_expired(&timer) == false); - osal_usleep(timeout_us - 2000); - ASSERT(osal_timer_is_expired(&timer) == false); - osal_usleep(4000); - ASSERT(osal_timer_is_expired(&timer)); -} - -static void test_osal_timer(void) -{ - test_osal_timer_timeout_us(10 * 1000); /* 10ms */ - test_osal_timer_timeout_us(100 * 1000); /* 100ms */ - test_osal_timer_timeout_us(1000 * 1000); /* 1s */ - test_osal_timer_timeout_us(2000 * 1000); /* 2s */ -} - -#define USECS_PER_SEC 1000000 -#define USECS_PER_TICK (USECS_PER_SEC / CFG_TICKS_PER_SECOND) -#ifndef ABS -#define ABS(x) ((x) < 0 ? -(x) : (x)) -#endif - -static int32 time_difference_us(const ec_timet stop, const ec_timet start) -{ - int32 difference_us; - - ASSERT(stop.sec >= start.sec); - if (stop.sec == start.sec) - { - ASSERT(stop.usec >= start.usec); - } - - difference_us = (stop.sec - start.sec) * USECS_PER_SEC; - difference_us += ((int32)stop.usec - (int32)start.usec); - - ASSERT(difference_us >= 0); - return difference_us; -} - -/** - * Test osal_current_time() by using it for measuring how long an osal_usleep() - * takes, in specified number of microseconds. - */ -static void test_osal_current_time_for_delay_us(const int32 sleep_time_us) -{ - ec_timet start; - ec_timet stop; - int32 measurement_us; - int32 deviation_us; - const int32 usleep_accuracy_us = USECS_PER_TICK; - boolean is_deviation_within_tolerance; - - start = osal_current_time(); - osal_usleep(sleep_time_us); - stop = osal_current_time(); - - measurement_us = time_difference_us(stop, start); - deviation_us = ABS(measurement_us - sleep_time_us); - is_deviation_within_tolerance = deviation_us <= usleep_accuracy_us; - ASSERT(is_deviation_within_tolerance); -} - -static void test_osal_current_time(void) -{ - test_osal_current_time_for_delay_us(0); - test_osal_current_time_for_delay_us(1); - test_osal_current_time_for_delay_us(500); - test_osal_current_time_for_delay_us(999); - test_osal_current_time_for_delay_us(USECS_PER_TICK); - test_osal_current_time_for_delay_us(USECS_PER_TICK - 1); - test_osal_current_time_for_delay_us(USECS_PER_TICK + 1); - test_osal_current_time_for_delay_us(2 * 1000 * 1000); /* 2s */ -} - -#include - -static void test_oshw_htons(void) -{ - uint16 network; - uint16 host; - - host = 0x1234; - network = oshw_htons(host); - ASSERT(network == htons(host)); -} - -static void test_oshw_ntohs(void) -{ - uint16 host; - uint16 network; - - network = 0x1234; - host = oshw_ntohs(network); - ASSERT(host == ntohs(network)); -} - -int main(void) -{ - test_oshw_htons(); - test_oshw_ntohs(); - test_osal_timer(); - test_osal_current_time(); - - rprintp("SOEM (Simple Open EtherCAT Master)\nSimple test\n"); - - task_spawn("simpletest", simpletest, 9, 8192, NULL); - - return (0); -} diff --git a/test/rtk/schedule.tt b/test/rtk/schedule.tt deleted file mode 100644 index dd9fce1..0000000 --- a/test/rtk/schedule.tt +++ /dev/null @@ -1,14 +0,0 @@ -stack_size: 2048 - -tasks: - - name : tReadIO - entry : read_io - arg : 'NULL' - -schedules: - - name : sched1 - period : 1 - events : - - task : tReadIO - start : 0 - stop : 1 \ No newline at end of file diff --git a/test/win32/ebox/ebox.c b/test/win32/ebox/ebox.c deleted file mode 100644 index fc410ce..0000000 --- a/test/win32/ebox/ebox.c +++ /dev/null @@ -1,398 +0,0 @@ -/** \file - * \brief Example code for Simple Open EtherCAT master - * - * Usage : ebox [ifname] [cycletime] - * ifname is NIC interface, f.e. eth0 - * cycletime in us, f.e. 500 - * - * This test is specifically build for the E/BOX. - * - * (c)Arthur Ketels 2011 - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ethercat.h" - -#define NSEC_PER_SEC 1000000000 - -typedef struct PACKED -{ - uint8 status; - uint8 counter; - uint8 din; - int32 ain[2]; - uint32 tsain; - int32 enc[2]; -} in_EBOXt; - -typedef struct PACKED -{ - uint8 counter; - int16 stream[100]; -} in_EBOX_streamt; - -typedef struct PACKED -{ - uint8 control; - uint8 dout; - int16 aout[2]; - uint16 pwmout[2]; -} out_EBOXt; - -typedef struct PACKED -{ - uint8 control; -} out_EBOX_streamt; - -// total samples to capture -#define MAXSTREAM 200000 -// sample interval in ns, here 8us -> 125kHz -// maximum data rate for E/BOX v1.0.1 is around 150kHz -#define SYNC0TIME 8000 - -struct sched_param schedp; -char IOmap[4096]; -pthread_t thread1; -struct timeval tv, t1, t2; -int dorun = 0; -int deltat, tmax = 0; -int64 toff; -int DCdiff; -int os; -uint32 ob; -int16 ob2; -uint8 ob3; -pthread_cond_t cond = PTHREAD_COND_INITIALIZER; -pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; -int64 integral = 0; -uint32 cyclecount; -in_EBOX_streamt *in_EBOX; -out_EBOX_streamt *out_EBOX; -double ain[2]; -int ainc; -int streampos; -int16 stream1[MAXSTREAM]; -int16 stream2[MAXSTREAM]; - -int output_cvs(char *fname, int length) -{ - FILE *fp; - - int i; - - fp = fopen(fname, "w"); - if (fp == NULL) - return 0; - for (i = 0; i < length; i++) - { - fprintf(fp, "%d %d %d\n", i, stream1[i], stream2[i]); - } - fclose(fp); - - return 1; -} - -void eboxtest(char *ifname) -{ - int cnt, i; - - printf("Starting E/BOX test\n"); - - /* initialise SOEM, bind socket to ifname */ - if (ec_init(ifname)) - { - printf("ec_init on %s succeeded.\n", ifname); - /* find and auto-config slaves */ - if (ec_config_init(FALSE) > 0) - { - printf("%d slaves found and configured.\n", ec_slavecount); - - // check if first slave is an E/BOX - if ((ec_slavecount >= 1) && - (strcmp(ec_slave[1].name, "E/BOX") == 0)) - { - // reprogram PDO mapping to set slave in stream mode - // this can only be done in pre-OP state - os = sizeof(ob2); - ob2 = 0x1601; - ec_SDOwrite(1, 0x1c12, 01, FALSE, os, &ob2, EC_TIMEOUTRXM); - os = sizeof(ob2); - ob2 = 0x1a01; - ec_SDOwrite(1, 0x1c13, 01, FALSE, os, &ob2, EC_TIMEOUTRXM); - } - - ec_config_map(&IOmap); - - ec_configdc(); - - /* wait for all slaves to reach SAFE_OP state */ - ec_statecheck(0, EC_STATE_SAFE_OP, EC_TIMEOUTSTATE); - - /* configure DC options for every DC capable slave found in the list */ - printf("DC capable : %d\n", ec_configdc()); - - /* check configuration */ - if ((ec_slavecount >= 1) && - (strcmp(ec_slave[1].name, "E/BOX") == 0)) - { - printf("E/BOX found.\n"); - - /* connect struct pointers to slave I/O pointers */ - in_EBOX = (in_EBOX_streamt *)ec_slave[1].inputs; - out_EBOX = (out_EBOX_streamt *)ec_slave[1].outputs; - - /* read indevidual slave state and store in ec_slave[] */ - ec_readstate(); - for (cnt = 1; cnt <= ec_slavecount; cnt++) - { - printf("Slave:%d Name:%s Output size:%3dbits Input size:%3dbits State:%2d delay:%d.%d\n", - cnt, ec_slave[cnt].name, ec_slave[cnt].Obits, ec_slave[cnt].Ibits, - ec_slave[cnt].state, (int)ec_slave[cnt].pdelay, ec_slave[cnt].hasdc); - } - printf("Request operational state for all slaves\n"); - - /* send one processdata cycle to init SM in slaves */ - ec_send_processdata(); - ec_receive_processdata(EC_TIMEOUTRET); - - ec_slave[0].state = EC_STATE_OPERATIONAL; - /* request OP state for all slaves */ - ec_writestate(0); - /* wait for all slaves to reach OP state */ - ec_statecheck(0, EC_STATE_OPERATIONAL, EC_TIMEOUTSTATE); - if (ec_slave[0].state == EC_STATE_OPERATIONAL) - { - printf("Operational state reached for all slaves.\n"); - ain[0] = 0; - ain[1] = 0; - ainc = 0; - dorun = 1; - usleep(100000); // wait for linux to sync on DC - ec_dcsync0(1, TRUE, SYNC0TIME, 0); // SYNC0 on slave 1 - /* acyclic loop 20ms */ - for (i = 1; i <= 200; i++) - { - /* read DC difference register for slave 2 */ - // ec_FPRD(ec_slave[1].configadr, ECT_REG_DCSYSDIFF, sizeof(DCdiff), &DCdiff, EC_TIMEOUTRET); - // if(DCdiff<0) { DCdiff = - (int32)((uint32)DCdiff & 0x7ffffff); } - printf("PD cycle %5d DCtime %12lld Cnt:%3d Data: %6d %6d %6d %6d %6d %6d %6d %6d \n", - cyclecount, ec_DCtime, in_EBOX->counter, in_EBOX->stream[0], in_EBOX->stream[1], - in_EBOX->stream[2], in_EBOX->stream[3], in_EBOX->stream[4], in_EBOX->stream[5], - in_EBOX->stream[98], in_EBOX->stream[99]); - usleep(20000); - } - dorun = 0; - // printf("\nCnt %d : Ain0 = %f Ain2 = %f\n", ainc, ain[0] / ainc, ain[1] / ainc); - } - else - { - printf("Not all slaves reached operational state.\n"); - } - } - else - { - printf("E/BOX not found in slave configuration.\n"); - } - ec_dcsync0(1, FALSE, 8000, 0); // SYNC0 off - printf("Request safe operational state for all slaves\n"); - ec_slave[0].state = EC_STATE_SAFE_OP; - /* request SAFE_OP state for all slaves */ - ec_writestate(0); - /* wait for all slaves to reach state */ - ec_statecheck(0, EC_STATE_SAFE_OP, EC_TIMEOUTSTATE); - ec_slave[0].state = EC_STATE_PRE_OP; - /* request SAFE_OP state for all slaves */ - ec_writestate(0); - /* wait for all slaves to reach state */ - ec_statecheck(0, EC_STATE_PRE_OP, EC_TIMEOUTSTATE); - if ((ec_slavecount >= 1) && - (strcmp(ec_slave[1].name, "E/BOX") == 0)) - { - // restore PDO to standard mode - // this can only be done is pre-op state - os = sizeof(ob2); - ob2 = 0x1600; - ec_SDOwrite(1, 0x1c12, 01, FALSE, os, &ob2, EC_TIMEOUTRXM); - os = sizeof(ob2); - ob2 = 0x1a00; - ec_SDOwrite(1, 0x1c13, 01, FALSE, os, &ob2, EC_TIMEOUTRXM); - } - printf("Streampos %d\n", streampos); - output_cvs("stream.txt", streampos); - } - else - { - printf("No slaves found!\n"); - } - printf("End E/BOX, close socket\n"); - /* stop SOEM, close socket */ - ec_close(); - } - else - { - printf("No socket connection on %s\nExcecute as root\n", ifname); - } -} - -/* add ns to timespec */ -void add_timespec(struct timespec *ts, int64 addtime) -{ - int64 sec, nsec; - - nsec = addtime % NSEC_PER_SEC; - sec = (addtime - nsec) / NSEC_PER_SEC; - ts->tv_sec += sec; - ts->tv_nsec += nsec; - if (ts->tv_nsec >= NSEC_PER_SEC) - { - nsec = ts->tv_nsec % NSEC_PER_SEC; - ts->tv_sec += (ts->tv_nsec - nsec) / NSEC_PER_SEC; - ts->tv_nsec = nsec; - } -} - -/* PI calculation to get linux time synced to DC time */ -void ec_sync(int64 reftime, int64 cycletime, int64 *offsettime) -{ - int64 delta; - /* set linux sync point 50us later than DC sync, just as example */ - delta = (reftime - 50000) % cycletime; - if (delta > (cycletime / 2)) - { - delta = delta - cycletime; - } - if (delta > 0) - { - integral++; - } - if (delta < 0) - { - integral--; - } - *offsettime = -(delta / 100) - (integral / 20); -} - -/* RT EtherCAT thread */ -void ecatthread(void *ptr) -{ - struct timespec ts; - struct timeval tp; - int rc; - int ht; - int i; - int pcounter = 0; - int64 cycletime; - - rc = pthread_mutex_lock(&mutex); - rc = gettimeofday(&tp, NULL); - - /* Convert from timeval to timespec */ - ts.tv_sec = tp.tv_sec; - ht = (tp.tv_usec / 1000) + 1; /* round to nearest ms */ - ts.tv_nsec = ht * 1000000; - cycletime = *(int *)ptr * 1000; /* cycletime in ns */ - toff = 0; - dorun = 0; - while (1) - { - /* calculate next cycle start */ - add_timespec(&ts, cycletime + toff); - /* wait to cycle start */ - rc = pthread_cond_timedwait(&cond, &mutex, &ts); - if (dorun > 0) - { - rc = gettimeofday(&tp, NULL); - - ec_send_processdata(); - - ec_receive_processdata(EC_TIMEOUTRET); - - cyclecount++; - - if ((in_EBOX->counter != pcounter) && (streampos < (MAXSTREAM - 1))) - { - // check if we have timing problems in master - // if so, overwrite stream data so it shows up clearly in plots. - if (in_EBOX->counter > (pcounter + 1)) - { - for (i = 0; i < 50; i++) - { - stream1[streampos] = 20000; - stream2[streampos++] = -20000; - } - } - else - { - for (i = 0; i < 50; i++) - { - stream1[streampos] = in_EBOX->stream[i * 2]; - stream2[streampos++] = in_EBOX->stream[(i * 2) + 1]; - } - } - pcounter = in_EBOX->counter; - } - - /* calulate toff to get linux time and DC synced */ - ec_sync(ec_DCtime, cycletime, &toff); - } - } -} - -int main(int argc, char *argv[]) -{ - int iret1; - int ctime; - struct sched_param param; - int policy = SCHED_OTHER; - - printf("SOEM (Simple Open EtherCAT Master)\nE/BOX test\n"); - - memset(&schedp, 0, sizeof(schedp)); - /* do not set priority above 49, otherwise sockets are starved */ - schedp.sched_priority = 30; - sched_setscheduler(0, SCHED_FIFO, &schedp); - - do - { - usleep(1000); - } while (dorun); - - if (argc > 1) - { - dorun = 1; - if (argc > 2) - ctime = atoi(argv[2]); - else - ctime = 1000; // 1ms cycle time - /* create RT thread */ - iret1 = pthread_create(&thread1, NULL, (void *)&ecatthread, (void *)&ctime); - memset(¶m, 0, sizeof(param)); - /* give it higher priority */ - param.sched_priority = 40; - iret1 = pthread_setschedparam(thread1, policy, ¶m); - - /* start acyclic part */ - eboxtest(argv[1]); - } - else - { - printf("Usage: ebox ifname [cycletime]\nifname = eth0 for example\ncycletime in us\n"); - } - - schedp.sched_priority = 0; - sched_setscheduler(0, SCHED_OTHER, &schedp); - - printf("End program\n"); - - return (0); -} diff --git a/test/win32/eepromtool/eepromtool.c b/test/win32/eepromtool/eepromtool.c deleted file mode 100644 index 34b822d..0000000 --- a/test/win32/eepromtool/eepromtool.c +++ /dev/null @@ -1,389 +0,0 @@ -/** \file - * \brief EEprom tool for Simple Open EtherCAT master - * - * Usage : eepromtool ifname slave OPTION fname - * ifname is NIC interface, f.e. eth0 - * slave = slave number in EtherCAT order 1..n - * -r read EEPROM, output binary format - * -ri read EEPROM, output Intel Hex format - * -w write EEPROM, input binary format - * -wi write EEPROM, input Intel Hex format - * - * (c)Arthur Ketels 2010 - */ - -#include -#include -#include - -#include "ethercat.h" - -#define MAXBUF 32768 -#define STDBUF 2048 -#define MINBUF 128 - -#define MODE_NONE 0 -#define MODE_READBIN 1 -#define MODE_READINTEL 2 -#define MODE_WRITEBIN 3 -#define MODE_WRITEINTEL 4 - -#define MAXSLENGTH 256 - -uint8 ebuf[MAXBUF]; -uint8 ob; -uint16 ow; -int os; -int slave; -ec_timet tstart, tend, tdif; -int wkc; -int mode; -char sline[MAXSLENGTH]; - -#define IHEXLENGTH 0x20 - -int input_bin(char *fname, int *length) -{ - FILE *fp; - - int cc = 0, c; - - fp = fopen(fname, "rb"); - if (fp == NULL) - return 0; - while (((c = fgetc(fp)) != EOF) && (cc < MAXBUF)) - ebuf[cc++] = (uint8)c; - *length = cc; - fclose(fp); - - return 1; -} - -int input_intelhex(char *fname, int *start, int *length) -{ - FILE *fp; - - int c, sc, retval = 1; - int ll, ladr, lt, sn, i, lval; - int hstart, hlength, sum; - - fp = fopen(fname, "r"); - if (fp == NULL) - return 0; - hstart = MAXBUF; - hlength = 0; - sum = 0; - do - { - memset(sline, 0x00, MAXSLENGTH); - sc = 0; - while (((c = fgetc(fp)) != EOF) && (c != 0x0A) && (sc < (MAXSLENGTH - 1))) - sline[sc++] = (uint8)c; - if ((c != EOF) && ((sc < 11) || (sline[0] != ':'))) - { - c = EOF; - retval = 0; - printf("Invalid Intel Hex format.\n"); - } - if (c != EOF) - { - sn = sscanf(sline, ":%2x%4x%2x", &ll, &ladr, <); - if ((sn == 3) && ((ladr + ll) <= MAXBUF) && (lt == 0)) - { - sum = ll + (ladr >> 8) + (ladr & 0xff) + lt; - if (ladr < hstart) hstart = ladr; - for (i = 0; i < ll; i++) - { - sn = sscanf(&sline[9 + (i << 1)], "%2x", &lval); - ebuf[ladr + i] = (uint8)lval; - sum += (uint8)lval; - } - if (((ladr + ll) - hstart) > hlength) - hlength = (ladr + ll) - hstart; - sum = (0x100 - sum) & 0xff; - sn = sscanf(&sline[9 + (i << 1)], "%2x", &lval); - if (!sn || ((sum - lval) != 0)) - { - c = EOF; - retval = 0; - printf("Invalid checksum.\n"); - } - } - } - } while (c != EOF); - if (retval) - { - *length = hlength; - *start = hstart; - } - fclose(fp); - - return retval; -} - -int output_bin(char *fname, int length) -{ - FILE *fp; - - int cc; - - fp = fopen(fname, "wb"); - if (fp == NULL) - return 0; - for (cc = 0; cc < length; cc++) - fputc(ebuf[cc], fp); - fclose(fp); - - return 1; -} - -int output_intelhex(char *fname, int length) -{ - FILE *fp; - - int cc = 0, ll, sum, i; - - fp = fopen(fname, "w"); - if (fp == NULL) - return 0; - while (cc < length) - { - ll = length - cc; - if (ll > IHEXLENGTH) ll = IHEXLENGTH; - sum = ll + (cc >> 8) + (cc & 0xff); - fprintf(fp, ":%2.2X%4.4X00", ll, cc); - for (i = 0; i < ll; i++) - { - fprintf(fp, "%2.2X", ebuf[cc + i]); - sum += ebuf[cc + i]; - } - fprintf(fp, "%2.2X\n", (0x100 - sum) & 0xff); - cc += ll; - } - fprintf(fp, ":00000001FF\n"); - fclose(fp); - - return 1; -} - -int eeprom_read(int slave, int start, int length) -{ - int i, wkc, ainc = 4; - uint16 estat, aiadr; - uint32 b4; - uint64 b8; - uint8 eepctl; - - if ((ec_slavecount >= slave) && (slave > 0) && ((start + length) <= MAXBUF)) - { - aiadr = 1 - slave; - eepctl = 2; - wkc = ec_APWR(aiadr, ECT_REG_EEPCFG, sizeof(eepctl), &eepctl, EC_TIMEOUTRET3); /* force Eeprom from PDI */ - eepctl = 0; - wkc = ec_APWR(aiadr, ECT_REG_EEPCFG, sizeof(eepctl), &eepctl, EC_TIMEOUTRET3); /* set Eeprom to master */ - - estat = 0x0000; - aiadr = 1 - slave; - wkc = ec_APRD(aiadr, ECT_REG_EEPSTAT, sizeof(estat), &estat, EC_TIMEOUTRET3); /* read eeprom status */ - estat = etohs(estat); - if (estat & EC_ESTAT_R64) - { - ainc = 8; - for (i = start; i < (start + length); i += ainc) - { - b8 = ec_readeepromAP(aiadr, i >> 1, EC_TIMEOUTEEP); - ebuf[i] = (uint8)b8; - ebuf[i + 1] = (uint8)(b8 >> 8); - ebuf[i + 2] = (uint8)(b8 >> 16); - ebuf[i + 3] = (uint8)(b8 >> 24); - ebuf[i + 4] = (uint8)(b8 >> 32); - ebuf[i + 5] = (uint8)(b8 >> 40); - ebuf[i + 6] = (uint8)(b8 >> 48); - ebuf[i + 7] = (uint8)(b8 >> 56); - } - } - else - { - for (i = start; i < (start + length); i += ainc) - { - b4 = (uint32)ec_readeepromAP(aiadr, i >> 1, EC_TIMEOUTEEP); - ebuf[i] = (uint8)b4; - ebuf[i + 1] = (uint8)(b4 >> 8); - ebuf[i + 2] = (uint8)(b4 >> 16); - ebuf[i + 3] = (uint8)(b4 >> 24); - } - } - - return 1; - } - - return 0; -} - -int eeprom_write(int slave, int start, int length) -{ - int i, wkc, dc = 0; - uint16 aiadr, *wbuf; - uint8 eepctl; - int ret; - - if ((ec_slavecount >= slave) && (slave > 0) && ((start + length) <= MAXBUF)) - { - aiadr = 1 - slave; - eepctl = 2; - wkc = ec_APWR(aiadr, ECT_REG_EEPCFG, sizeof(eepctl), &eepctl, EC_TIMEOUTRET3); /* force Eeprom from PDI */ - eepctl = 0; - wkc = ec_APWR(aiadr, ECT_REG_EEPCFG, sizeof(eepctl), &eepctl, EC_TIMEOUTRET3); /* set Eeprom to master */ - - aiadr = 1 - slave; - wbuf = (uint16 *)&ebuf[0]; - for (i = start; i < (start + length); i += 2) - { - ret = ec_writeeepromAP(aiadr, i >> 1, *(wbuf + (i >> 1)), EC_TIMEOUTEEP); - if (++dc >= 100) - { - dc = 0; - printf("."); - fflush(stdout); - } - } - - return 1; - } - - return 0; -} - -void eepromtool(char *ifname, int slave, int mode, char *fname) -{ - int w, rc = 0, estart, esize; - uint16 *wbuf; - - /* initialise SOEM, bind socket to ifname */ - if (ec_init(ifname)) - { - printf("ec_init on %s succeeded.\n", ifname); - - w = 0x0000; - wkc = ec_BRD(0x0000, ECT_REG_TYPE, sizeof(w), &w, EC_TIMEOUTSAFE); /* detect number of slaves */ - if (wkc > 0) - { - ec_slavecount = wkc; - - printf("%d slaves found.\n", ec_slavecount); - if ((ec_slavecount >= slave) && (slave > 0)) - { - if ((mode == MODE_READBIN) || (mode == MODE_READINTEL)) - { - tstart = osal_current_time(); - eeprom_read(slave, 0x0000, MINBUF); // read first 128 bytes - - wbuf = (uint16 *)&ebuf[0]; - printf("Slave %d data\n", slave); - printf(" PDI Control : %4.4X\n", *(wbuf + 0x00)); - printf(" PDI Config : %4.4X\n", *(wbuf + 0x01)); - printf(" Config Alias : %4.4X\n", *(wbuf + 0x04)); - printf(" Checksum : %4.4X\n", *(wbuf + 0x07)); - printf(" Vendor ID : %8.8X\n", *(uint32 *)(wbuf + 0x08)); - printf(" Product Code : %8.8X\n", *(uint32 *)(wbuf + 0x0A)); - printf(" Revision Number : %8.8X\n", *(uint32 *)(wbuf + 0x0C)); - printf(" Serial Number : %8.8X\n", *(uint32 *)(wbuf + 0x0E)); - printf(" Mailbox Protocol : %4.4X\n", *(wbuf + 0x1C)); - esize = (*(wbuf + 0x3E) + 1) * 128; - if (esize > MAXBUF) esize = MAXBUF; - printf(" Size : %4.4X = %d bytes\n", *(wbuf + 0x3E), esize); - printf(" Version : %4.4X\n", *(wbuf + 0x3F)); - - if (esize > MINBUF) - eeprom_read(slave, MINBUF, esize - MINBUF); // read reminder - - tend = osal_current_time(); - osal_time_diff(&tstart, &tend, &tdif); - if (mode == MODE_READINTEL) output_intelhex(fname, esize); - if (mode == MODE_READBIN) output_bin(fname, esize); - - printf("\nTotal EEPROM read time :%ldms\n", (tdif.usec + (tdif.sec * 1000000L)) / 1000); - } - if ((mode == MODE_WRITEBIN) || (mode == MODE_WRITEINTEL)) - { - estart = 0; - if (mode == MODE_WRITEINTEL) rc = input_intelhex(fname, &estart, &esize); - if (mode == MODE_WRITEBIN) rc = input_bin(fname, &esize); - - if (rc > 0) - { - wbuf = (uint16 *)&ebuf[0]; - printf("Slave %d\n", slave); - printf(" Vendor ID : %8.8X\n", *(uint32 *)(wbuf + 0x08)); - printf(" Product Code : %8.8X\n", *(uint32 *)(wbuf + 0x0A)); - printf(" Revision Number : %8.8X\n", *(uint32 *)(wbuf + 0x0C)); - printf(" Serial Number : %8.8X\n", *(uint32 *)(wbuf + 0x0E)); - - printf("Busy"); - fflush(stdout); - tstart = osal_current_time(); - eeprom_write(slave, estart, esize); - tend = osal_current_time(); - osal_time_diff(&tstart, &tend, &tdif); - - printf("\nTotal EEPROM write time :%ldms\n", (tdif.usec + (tdif.sec * 1000000L)) / 1000); - } - else - printf("Error reading file, abort.\n"); - } - } - else - printf("Slave number outside range.\n"); - } - else - printf("No slaves found!\n"); - printf("End, close socket\n"); - /* stop SOEM, close socket */ - ec_close(); - } - else - printf("No socket connection on %s\nExcecute as root\n", ifname); -} - -int main(int argc, char *argv[]) -{ - ec_adaptert *adapter = NULL; - ec_adaptert *head = NULL; - printf("SOEM (Simple Open EtherCAT Master)\nEEPROM tool\n"); - - if (argc > 4) - { - slave = atoi(argv[2]); - mode = MODE_NONE; - if ((strncmp(argv[3], "-r", sizeof("-r")) == 0)) mode = MODE_READBIN; - if ((strncmp(argv[3], "-ri", sizeof("-ri")) == 0)) mode = MODE_READINTEL; - if ((strncmp(argv[3], "-w", sizeof("-w")) == 0)) mode = MODE_WRITEBIN; - if ((strncmp(argv[3], "-wi", sizeof("-wi")) == 0)) mode = MODE_WRITEINTEL; - - /* start tool */ - eepromtool(argv[1], slave, mode, argv[4]); - } - else - { - printf("Usage: eepromtool ifname slave OPTION fname\n"); - printf("ifname = adapter name\n"); - printf("slave = slave number in EtherCAT order 1..n\n"); - printf(" -r read EEPROM, output binary format\n"); - printf(" -ri read EEPROM, output Intel Hex format\n"); - printf(" -w write EEPROM, input binary format\n"); - printf(" -wi write EEPROM, input Intel Hex format\n"); - /* Print the list */ - printf("Available adapters\n"); - head = adapter = ec_find_adapters(); - while (adapter != NULL) - { - printf("Description : %s, Device to use for wpcap: %s\n", adapter->desc, adapter->name); - adapter = adapter->next; - } - ec_free_adapters(adapter); - } - - printf("End program\n"); - - return (0); -} diff --git a/test/win32/firm_update/firm_update.c b/test/win32/firm_update/firm_update.c deleted file mode 100644 index d4c7c27..0000000 --- a/test/win32/firm_update/firm_update.c +++ /dev/null @@ -1,156 +0,0 @@ -/** \file - * \brief Example code for Simple Open EtherCAT master - * - * Usage: firm_update ifname1 slave fname - * ifname is NIC interface, f.e. eth0 - * slave = slave number in EtherCAT order 1..n - * fname = binary file to store in slave - * CAUTION! Using the wrong file can result in a bricked slave! - * - * This is a slave firmware update test. - * - * (c)Arthur Ketels 2011 - */ - -#include -#include -#include -#include -#include - -#include "ethercat.h" - -#define FWBUFSIZE (8 * 1024 * 1024) - -uint8 ob; -uint16 ow; -uint32 data; -char filename[256]; -char filebuffer[FWBUFSIZE]; // 8MB buffer -int filesize; -int j; -uint16 argslave; - -int input_bin(char *fname, int *length) -{ - FILE *fp; - - int cc = 0, c; - - fp = fopen(fname, "rb"); - if (fp == NULL) - return 0; - while (((c = fgetc(fp)) != EOF) && (cc < FWBUFSIZE)) - filebuffer[cc++] = (uint8)c; - *length = cc; - fclose(fp); - return 1; -} - -void boottest(char *ifname, uint16 slave, char *filename) -{ - printf("Starting firmware update example\n"); - - /* initialise SOEM, bind socket to ifname */ - if (ec_init(ifname)) - { - printf("ec_init on %s succeeded.\n", ifname); - /* find and auto-config slaves */ - - if (ec_config_init(FALSE) > 0) - { - printf("%d slaves found and configured.\n", ec_slavecount); - - printf("Request init state for slave %d\n", slave); - ec_slave[slave].state = EC_STATE_INIT; - ec_writestate(slave); - - /* wait for slave to reach INIT state */ - ec_statecheck(slave, EC_STATE_INIT, EC_TIMEOUTSTATE * 4); - printf("Slave %d state to INIT.\n", slave); - - /* read BOOT mailbox data, master -> slave */ - data = ec_readeeprom(slave, ECT_SII_BOOTRXMBX, EC_TIMEOUTEEP); - ec_slave[slave].SM[0].StartAddr = (uint16)LO_WORD(data); - ec_slave[slave].SM[0].SMlength = (uint16)HI_WORD(data); - /* store boot write mailbox address */ - ec_slave[slave].mbx_wo = (uint16)LO_WORD(data); - /* store boot write mailbox size */ - ec_slave[slave].mbx_l = (uint16)HI_WORD(data); - - /* read BOOT mailbox data, slave -> master */ - data = ec_readeeprom(slave, ECT_SII_BOOTTXMBX, EC_TIMEOUTEEP); - ec_slave[slave].SM[1].StartAddr = (uint16)LO_WORD(data); - ec_slave[slave].SM[1].SMlength = (uint16)HI_WORD(data); - /* store boot read mailbox address */ - ec_slave[slave].mbx_ro = (uint16)LO_WORD(data); - /* store boot read mailbox size */ - ec_slave[slave].mbx_rl = (uint16)HI_WORD(data); - - printf(" SM0 A:%4.4x L:%4d F:%8.8x\n", ec_slave[slave].SM[0].StartAddr, ec_slave[slave].SM[0].SMlength, - (int)ec_slave[slave].SM[0].SMflags); - printf(" SM1 A:%4.4x L:%4d F:%8.8x\n", ec_slave[slave].SM[1].StartAddr, ec_slave[slave].SM[1].SMlength, - (int)ec_slave[slave].SM[1].SMflags); - /* program SM0 mailbox in for slave */ - ec_FPWR(ec_slave[slave].configadr, ECT_REG_SM0, sizeof(ec_smt), &ec_slave[slave].SM[0], EC_TIMEOUTRET); - /* program SM1 mailbox out for slave */ - ec_FPWR(ec_slave[slave].configadr, ECT_REG_SM1, sizeof(ec_smt), &ec_slave[slave].SM[1], EC_TIMEOUTRET); - - printf("Request BOOT state for slave %d\n", slave); - ec_slave[slave].state = EC_STATE_BOOT; - ec_writestate(slave); - - /* wait for slave to reach BOOT state */ - if (ec_statecheck(slave, EC_STATE_BOOT, EC_TIMEOUTSTATE * 10) == EC_STATE_BOOT) - { - printf("Slave %d state to BOOT.\n", slave); - - if (input_bin(filename, &filesize)) - { - printf("File read OK, %d bytes.\n", filesize); - printf("FoE write...."); - j = ec_FOEwrite(slave, filename, 0, filesize, &filebuffer, EC_TIMEOUTSTATE); - printf("result %d.\n", j); - printf("Request init state for slave %d\n", slave); - ec_slave[slave].state = EC_STATE_INIT; - ec_writestate(slave); - } - else - printf("File not read OK.\n"); - } - } - else - { - printf("No slaves found!\n"); - } - printf("End firmware update example, close socket\n"); - /* stop SOEM, close socket */ - ec_close(); - } - else - { - printf("No socket connection on %s\nExcecute as root\n", ifname); - } -} - -int main(int argc, char *argv[]) -{ - printf("SOEM (Simple Open EtherCAT Master)\nFirmware update example\n"); - - if (argc > 3) - { - argslave = atoi(argv[2]); - boottest(argv[1], argslave, argv[3]); - } - else - { - printf("Usage: firm_update ifname1 slave fname\n"); - printf("ifname = eth0 for example\n"); - printf("slave = slave number in EtherCAT order 1..n\n"); - printf("fname = binary file to store in slave\n"); - printf("CAUTION! Using the wrong file can result in a bricked slave!\n"); - } - - printf("End program\n"); - return (0); -} diff --git a/test/win32/red_test/red_test.c b/test/win32/red_test/red_test.c deleted file mode 100644 index 4f69e67..0000000 --- a/test/win32/red_test/red_test.c +++ /dev/null @@ -1,265 +0,0 @@ -/** \file - * \brief Example code for Simple Open EtherCAT master - * - * Usage : red_test [ifname1] [ifname2] [cycletime] - * ifname is NIC interface, f.e. eth0 - * cycletime in us, f.e. 500 - * - * This is a redundancy test. - * - * (c)Arthur Ketels 2008 - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ethercat.h" - -#define NSEC_PER_SEC 1000000000 - -struct sched_param schedp; -char IOmap[4096]; -pthread_t thread1; -struct timeval tv, t1, t2; -int dorun = 0; -int deltat, tmax = 0; -int64 toff; -int DCdiff; -int os; -uint8 ob; -uint16 ob2; -pthread_cond_t cond = PTHREAD_COND_INITIALIZER; -pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; -uint8 *digout = 0; -int wcounter; - -void redtest(char *ifname, char *ifname2) -{ - int cnt, i, j, oloop, iloop; - - printf("Starting Redundant test\n"); - - /* initialise SOEM, bind socket to ifname */ - if (ec_init_redundant(ifname, ifname2)) - { - printf("ec_init on %s succeeded.\n", ifname); - /* find and auto-config slaves */ - if (ec_config(FALSE, &IOmap) > 0) - { - printf("%d slaves found and configured.\n", ec_slavecount); - /* wait for all slaves to reach SAFE_OP state */ - ec_statecheck(0, EC_STATE_SAFE_OP, EC_TIMEOUTSTATE); - - /* configure DC options for every DC capable slave found in the list */ - ec_configdc(); - - /* read indevidual slave state and store in ec_slave[] */ - ec_readstate(); - for (cnt = 1; cnt <= ec_slavecount; cnt++) - { - printf("Slave:%d Name:%s Output size:%3dbits Input size:%3dbits State:%2d delay:%d.%d\n", - cnt, ec_slave[cnt].name, ec_slave[cnt].Obits, ec_slave[cnt].Ibits, - ec_slave[cnt].state, (int)ec_slave[cnt].pdelay, ec_slave[cnt].hasdc); - printf(" Out:%8.8x,%4d In:%8.8x,%4d\n", - (int)ec_slave[cnt].outputs, ec_slave[cnt].Obytes, (int)ec_slave[cnt].inputs, ec_slave[cnt].Ibytes); - /* check for EL2004 or EL2008 */ - if (!digout && ((ec_slave[cnt].eep_id == 0x07d43052) || (ec_slave[cnt].eep_id == 0x07d83052))) - { - digout = ec_slave[cnt].outputs; - } - } - printf("Request operational state for all slaves\n"); - ec_slave[0].state = EC_STATE_OPERATIONAL; - /* request OP state for all slaves */ - ec_writestate(0); - /* wait for all slaves to reach OP state */ - ec_statecheck(0, EC_STATE_OPERATIONAL, 5 * EC_TIMEOUTSTATE); - oloop = ec_slave[0].Obytes; - if ((oloop == 0) && (ec_slave[0].Obits > 0)) oloop = 1; - if (oloop > 8) oloop = 8; - iloop = ec_slave[0].Ibytes; - if ((iloop == 0) && (ec_slave[0].Ibits > 0)) iloop = 1; - if (iloop > 8) iloop = 8; - if (ec_slave[0].state == EC_STATE_OPERATIONAL) - { - printf("Operational state reached for all slaves.\n"); - dorun = 1; - /* acyclic loop 5000 x 20ms = 10s */ - for (i = 1; i <= 5000; i++) - { - printf("Processdata cycle %5d , Wck %3d, DCtime %12lld, O:", dorun, wcounter, ec_DCtime); - for (j = 0; j < oloop; j++) - { - printf(" %2.2x", *(ec_slave[0].outputs + j)); - } - printf(" I:"); - for (j = 0; j < iloop; j++) - { - printf(" %2.2x", *(ec_slave[0].inputs + j)); - } - printf("\n"); - usleep(20000); - } - dorun = 0; - } - else - { - printf("Not all slaves reached operational state.\n"); - } - printf("Request safe operational state for all slaves\n"); - ec_slave[0].state = EC_STATE_SAFE_OP; - /* request SAFE_OP state for all slaves */ - ec_writestate(0); - } - else - { - printf("No slaves found!\n"); - } - printf("End redundant test, close socket\n"); - /* stop SOEM, close socket */ - ec_close(); - } - else - { - printf("No socket connection on %s\nExcecute as root\n", ifname); - } -} - -/* add ns to timespec */ -void add_timespec(struct timespec *ts, int64 addtime) -{ - int64 sec, nsec; - - nsec = addtime % NSEC_PER_SEC; - sec = (addtime - nsec) / NSEC_PER_SEC; - ts->tv_sec += sec; - ts->tv_nsec += nsec; - if (ts->tv_nsec >= NSEC_PER_SEC) - { - nsec = ts->tv_nsec % NSEC_PER_SEC; - ts->tv_sec += (ts->tv_nsec - nsec) / NSEC_PER_SEC; - ts->tv_nsec = nsec; - } -} - -/* PI calculation to get linux time synced to DC time */ -void ec_sync(int64 reftime, int64 cycletime, int64 *offsettime) -{ - static int64 integral = 0; - int64 delta; - /* set linux sync point 50us later than DC sync, just as example */ - delta = (reftime - 50000) % cycletime; - if (delta > (cycletime / 2)) - { - delta = delta - cycletime; - } - if (delta > 0) - { - integral++; - } - if (delta < 0) - { - integral--; - } - *offsettime = -(delta / 100) - (integral / 20); -} - -/* RT EtherCAT thread */ -void ecatthread(void *ptr) -{ - struct timespec ts; - struct timeval tp; - int rc; - int ht; - int64 cycletime; - - rc = pthread_mutex_lock(&mutex); - rc = gettimeofday(&tp, NULL); - - /* Convert from timeval to timespec */ - ts.tv_sec = tp.tv_sec; - ht = (tp.tv_usec / 1000) + 1; /* round to nearest ms */ - ts.tv_nsec = ht * 1000000; - cycletime = *(int *)ptr * 1000; /* cycletime in ns */ - toff = 0; - dorun = 0; - while (1) - { - /* calculate next cycle start */ - add_timespec(&ts, cycletime + toff); - /* wait to cycle start */ - rc = pthread_cond_timedwait(&cond, &mutex, &ts); - if (dorun > 0) - { - rc = gettimeofday(&tp, NULL); - - ec_send_processdata(); - - wcounter = ec_receive_processdata(EC_TIMEOUTRET); - - dorun++; - /* if we have some digital output, cycle */ - if (digout) *digout = (uint8)((dorun / 16) & 0xff); - - if (ec_slave[0].hasdc) - { - /* calulate toff to get linux time and DC synced */ - ec_sync(ec_DCtime, cycletime, &toff); - } - } - } -} - -int main(int argc, char *argv[]) -{ - int iret1; - int ctime; - struct sched_param param; - int policy = SCHED_OTHER; - - printf("SOEM (Simple Open EtherCAT Master)\nRedundancy test\n"); - - memset(&schedp, 0, sizeof(schedp)); - /* do not set priority above 49, otherwise sockets are starved */ - schedp.sched_priority = 30; - sched_setscheduler(0, SCHED_FIFO, &schedp); - - do - { - usleep(1000); - } while (dorun); - - if (argc > 3) - { - dorun = 1; - ctime = atoi(argv[3]); - /* create RT thread */ - iret1 = pthread_create(&thread1, NULL, (void *)&ecatthread, (void *)&ctime); - memset(¶m, 0, sizeof(param)); - /* give it higher priority */ - param.sched_priority = 40; - iret1 = pthread_setschedparam(thread1, policy, ¶m); - - /* start acyclic part */ - redtest(argv[1], argv[2]); - } - else - { - printf("Usage: red_test ifname1 ifname2 cycletime\nifname = eth0 for example\ncycletime in us\n"); - } - - schedp.sched_priority = 0; - sched_setscheduler(0, SCHED_OTHER, &schedp); - - printf("End program\n"); - - return (0); -} diff --git a/test/win32/simple_test/simple_test.c b/test/win32/simple_test/simple_test.c deleted file mode 100644 index 83a990f..0000000 --- a/test/win32/simple_test/simple_test.c +++ /dev/null @@ -1,372 +0,0 @@ -/** \file - * \brief Example code for Simple Open EtherCAT master - * - * Usage : simple_test [ifname1] - * ifname is NIC interface, f.e. eth0 - * - * This is a minimal test. - * - * (c)Arthur Ketels 2010 - 2011 - */ - -#include -#include -// #include - -#include "osal.h" -#include "ethercat.h" - -#define EC_TIMEOUTMON 500 - -char IOmap[4096]; -OSAL_THREAD_HANDLE thread1; -int expectedWKC; -boolean needlf; -volatile int wkc; -volatile int rtcnt; -boolean inOP; -uint8 currentgroup = 0; - -/* most basic RT thread for process data, just does IO transfer */ -void CALLBACK RTthread(UINT uTimerID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2) -{ - IOmap[0]++; - - ec_send_processdata(); - wkc = ec_receive_processdata(EC_TIMEOUTRET); - rtcnt++; - /* do RT control stuff here */ -} - -int EL7031setup(uint16 slave) -{ - int retval; - uint16 u16val; - - // map velocity - uint16 map_1c12[4] = {0x0003, 0x1601, 0x1602, 0x1604}; - uint16 map_1c13[3] = {0x0002, 0x1a01, 0x1a03}; - - retval = 0; - - // Set PDO mapping using Complete Access - // Strange, writing CA works, reading CA doesn't - // This is a protocol error of the slave. - retval += ec_SDOwrite(slave, 0x1c12, 0x00, TRUE, sizeof(map_1c12), &map_1c12, EC_TIMEOUTSAFE); - retval += ec_SDOwrite(slave, 0x1c13, 0x00, TRUE, sizeof(map_1c13), &map_1c13, EC_TIMEOUTSAFE); - - // bug in EL7031 old firmware, CompleteAccess for reading is not supported even if the slave says it is. - ec_slave[slave].CoEdetails &= ~ECT_COEDET_SDOCA; - - // set some motor parameters, just as example - u16val = 1200; // max motor current in mA - // retval += ec_SDOwrite(slave, 0x8010, 0x01, FALSE, sizeof(u16val), &u16val, EC_TIMEOUTSAFE); - u16val = 150; // motor coil resistance in 0.01ohm - // retval += ec_SDOwrite(slave, 0x8010, 0x04, FALSE, sizeof(u16val), &u16val, EC_TIMEOUTSAFE); - - // set other nescessary parameters as needed - // ..... - - while (EcatError) - printf("%s", ec_elist2string()); - - printf("EL7031 slave %d set, retval = %d\n", slave, retval); - return 1; -} - -int AEPsetup(uint16 slave) -{ - int retval; - uint8 u8val; - uint16 u16val; - - retval = 0; - - u8val = 0; - retval += ec_SDOwrite(slave, 0x1c12, 0x00, FALSE, sizeof(u8val), &u8val, EC_TIMEOUTRXM); - u16val = 0x1603; - retval += ec_SDOwrite(slave, 0x1c12, 0x01, FALSE, sizeof(u16val), &u16val, EC_TIMEOUTRXM); - u8val = 1; - retval += ec_SDOwrite(slave, 0x1c12, 0x00, FALSE, sizeof(u8val), &u8val, EC_TIMEOUTRXM); - - u8val = 0; - retval += ec_SDOwrite(slave, 0x1c13, 0x00, FALSE, sizeof(u8val), &u8val, EC_TIMEOUTRXM); - u16val = 0x1a03; - retval += ec_SDOwrite(slave, 0x1c13, 0x01, FALSE, sizeof(u16val), &u16val, EC_TIMEOUTRXM); - u8val = 1; - retval += ec_SDOwrite(slave, 0x1c13, 0x00, FALSE, sizeof(u8val), &u8val, EC_TIMEOUTRXM); - - u8val = 8; - retval += ec_SDOwrite(slave, 0x6060, 0x00, FALSE, sizeof(u8val), &u8val, EC_TIMEOUTRXM); - - // set some motor parameters, just as example - u16val = 1200; // max motor current in mA - // retval += ec_SDOwrite(slave, 0x8010, 0x01, FALSE, sizeof(u16val), &u16val, EC_TIMEOUTSAFE); - u16val = 150; // motor coil resistance in 0.01ohm - // retval += ec_SDOwrite(slave, 0x8010, 0x04, FALSE, sizeof(u16val), &u16val, EC_TIMEOUTSAFE); - - // set other nescessary parameters as needed - // ..... - - while (EcatError) - printf("%s", ec_elist2string()); - - printf("AEP slave %d set, retval = %d\n", slave, retval); - return 1; -} - -void simpletest(char *ifname) -{ - int i, j, oloop, iloop, wkc_count, chk, slc; - UINT mmResult; - - needlf = FALSE; - inOP = FALSE; - - printf("Starting simple test\n"); - - /* initialise SOEM, bind socket to ifname */ - if (ec_init(ifname)) - { - printf("ec_init on %s succeeded.\n", ifname); - /* find and auto-config slaves */ - - if (ec_config_init(FALSE) > 0) - { - printf("%d slaves found and configured.\n", ec_slavecount); - - if ((ec_slavecount > 1)) - { - for (slc = 1; slc <= ec_slavecount; slc++) - { - // beckhoff EL7031, using ec_slave[].name is not very reliable - if ((ec_slave[slc].eep_man == 0x00000002) && (ec_slave[slc].eep_id == 0x1b773052)) - { - printf("Found %s at position %d\n", ec_slave[slc].name, slc); - // link slave specific setup to preop->safeop hook - ec_slave[slc].PO2SOconfig = &EL7031setup; - } - // Copley Controls EAP, using ec_slave[].name is not very reliable - if ((ec_slave[slc].eep_man == 0x000000ab) && (ec_slave[slc].eep_id == 0x00000380)) - { - printf("Found %s at position %d\n", ec_slave[slc].name, slc); - // link slave specific setup to preop->safeop hook - ec_slave[slc].PO2SOconfig = &AEPsetup; - } - } - } - - ec_config_map(&IOmap); - - ec_configdc(); - - printf("Slaves mapped, state to SAFE_OP.\n"); - /* wait for all slaves to reach SAFE_OP state */ - ec_statecheck(0, EC_STATE_SAFE_OP, EC_TIMEOUTSTATE * 4); - - oloop = ec_slave[0].Obytes; - if ((oloop == 0) && (ec_slave[0].Obits > 0)) oloop = 1; - if (oloop > 8) oloop = 8; - iloop = ec_slave[0].Ibytes; - if ((iloop == 0) && (ec_slave[0].Ibits > 0)) iloop = 1; - if (iloop > 8) iloop = 8; - - printf("segments : %d : %d %d %d %d\n", ec_group[0].nsegments, ec_group[0].IOsegment[0], ec_group[0].IOsegment[1], ec_group[0].IOsegment[2], ec_group[0].IOsegment[3]); - - printf("Request operational state for all slaves\n"); - expectedWKC = (ec_group[0].outputsWKC * 2) + ec_group[0].inputsWKC; - printf("Calculated workcounter %d\n", expectedWKC); - ec_slave[0].state = EC_STATE_OPERATIONAL; - /* send one valid process data to make outputs in slaves happy*/ - ec_send_processdata(); - ec_receive_processdata(EC_TIMEOUTRET); - - /* start RT thread as periodic MM timer */ - mmResult = timeSetEvent(1, 0, RTthread, 0, TIME_PERIODIC); - - /* request OP state for all slaves */ - ec_writestate(0); - chk = 200; - /* wait for all slaves to reach OP state */ - do - { - ec_statecheck(0, EC_STATE_OPERATIONAL, 50000); - } while (chk-- && (ec_slave[0].state != EC_STATE_OPERATIONAL)); - if (ec_slave[0].state == EC_STATE_OPERATIONAL) - { - printf("Operational state reached for all slaves.\n"); - wkc_count = 0; - inOP = TRUE; - - /* cyclic loop, reads data from RT thread */ - for (i = 1; i <= 500; i++) - { - if (wkc >= expectedWKC) - { - printf("Processdata cycle %4d, WKC %d , O:", rtcnt, wkc); - - for (j = 0; j < oloop; j++) - { - printf(" %2.2x", *(ec_slave[0].outputs + j)); - } - - printf(" I:"); - for (j = 0; j < iloop; j++) - { - printf(" %2.2x", *(ec_slave[0].inputs + j)); - } - printf(" T:%lld\r", ec_DCtime); - needlf = TRUE; - } - osal_usleep(50000); - } - inOP = FALSE; - } - else - { - printf("Not all slaves reached operational state.\n"); - ec_readstate(); - for (i = 1; i <= ec_slavecount; i++) - { - if (ec_slave[i].state != EC_STATE_OPERATIONAL) - { - printf("Slave %d State=0x%2.2x StatusCode=0x%4.4x : %s\n", - i, ec_slave[i].state, ec_slave[i].ALstatuscode, ec_ALstatuscode2string(ec_slave[i].ALstatuscode)); - } - } - } - - /* stop RT thread */ - timeKillEvent(mmResult); - - printf("\nRequest init state for all slaves\n"); - ec_slave[0].state = EC_STATE_INIT; - /* request INIT state for all slaves */ - ec_writestate(0); - } - else - { - printf("No slaves found!\n"); - } - printf("End simple test, close socket\n"); - /* stop SOEM, close socket */ - ec_close(); - } - else - { - printf("No socket connection on %s\nExcecute as root\n", ifname); - } -} - -// DWORD WINAPI ecatcheck( LPVOID lpParam ) -OSAL_THREAD_FUNC ecatcheck(void *lpParam) -{ - int slave; - - while (1) - { - if (inOP && ((wkc < expectedWKC) || ec_group[currentgroup].docheckstate)) - { - if (needlf) - { - needlf = FALSE; - printf("\n"); - } - /* one ore more slaves are not responding */ - ec_group[currentgroup].docheckstate = FALSE; - ec_readstate(); - for (slave = 1; slave <= ec_slavecount; slave++) - { - if ((ec_slave[slave].group == currentgroup) && (ec_slave[slave].state != EC_STATE_OPERATIONAL)) - { - ec_group[currentgroup].docheckstate = TRUE; - if (ec_slave[slave].state == (EC_STATE_SAFE_OP + EC_STATE_ERROR)) - { - printf("ERROR : slave %d is in SAFE_OP + ERROR, attempting ack.\n", slave); - ec_slave[slave].state = (EC_STATE_SAFE_OP + EC_STATE_ACK); - ec_writestate(slave); - } - else if (ec_slave[slave].state == EC_STATE_SAFE_OP) - { - printf("WARNING : slave %d is in SAFE_OP, change to OPERATIONAL.\n", slave); - ec_slave[slave].state = EC_STATE_OPERATIONAL; - ec_writestate(slave); - } - else if (ec_slave[slave].state > EC_STATE_NONE) - { - if (ec_reconfig_slave(slave, EC_TIMEOUTMON)) - { - ec_slave[slave].islost = FALSE; - printf("MESSAGE : slave %d reconfigured\n", slave); - } - } - else if (!ec_slave[slave].islost) - { - /* re-check state */ - ec_statecheck(slave, EC_STATE_OPERATIONAL, EC_TIMEOUTRET); - if (ec_slave[slave].state == EC_STATE_NONE) - { - ec_slave[slave].islost = TRUE; - printf("ERROR : slave %d lost\n", slave); - } - } - } - if (ec_slave[slave].islost) - { - if (ec_slave[slave].state == EC_STATE_NONE) - { - if (ec_recover_slave(slave, EC_TIMEOUTMON)) - { - ec_slave[slave].islost = FALSE; - printf("MESSAGE : slave %d recovered\n", slave); - } - } - else - { - ec_slave[slave].islost = FALSE; - printf("MESSAGE : slave %d found\n", slave); - } - } - } - if (!ec_group[currentgroup].docheckstate) - printf("OK : all slaves resumed OPERATIONAL.\n"); - } - osal_usleep(10000); - } - - return 0; -} - -char ifbuf[1024]; - -int main(int argc, char *argv[]) -{ - ec_adaptert *adapter = NULL; - ec_adaptert *head = NULL; - printf("SOEM (Simple Open EtherCAT Master)\nSimple test\n"); - - if (argc > 1) - { - /* create thread to handle slave error handling in OP */ - osal_thread_create(&thread1, 128000, &ecatcheck, NULL); - strcpy(ifbuf, argv[1]); - /* start cyclic part */ - simpletest(ifbuf); - } - else - { - printf("Usage: simple_test ifname1\n"); - /* Print the list */ - printf("Available adapters\n"); - head = adapter = ec_find_adapters(); - while (adapter != NULL) - { - printf("Description : %s, Device to use for wpcap: %s\n", adapter->desc, adapter->name); - adapter = adapter->next; - } - ec_free_adapters(adapter); - } - - printf("End program\n"); - return (0); -} diff --git a/test/win32/slaveinfo/slaveinfo.c b/test/win32/slaveinfo/slaveinfo.c deleted file mode 100644 index 90cc3a1..0000000 --- a/test/win32/slaveinfo/slaveinfo.c +++ /dev/null @@ -1,658 +0,0 @@ -/** \file - * \brief Example code for Simple Open EtherCAT master - * - * Usage : slaveinfo [ifname] [-sdo] [-map] - * Ifname is NIC interface, f.e. eth0. - * Optional -sdo to display CoE object dictionary. - * Optional -map to display slave PDO mapping - * - * This shows the configured slave data. - * - * (c)Arthur Ketels 2010 - 2011 - */ - -#include -#include -#include - -#include "ethercat.h" - -char IOmap[4096]; -ec_ODlistt ODlist; -ec_OElistt OElist; -boolean printSDO = FALSE; -boolean printMAP = FALSE; -char usdo[128]; -char hstr[1024]; - -char *dtype2string(uint16 dtype) -{ - switch (dtype) - { - case ECT_BOOLEAN: - sprintf(hstr, "BOOLEAN"); - break; - case ECT_INTEGER8: - sprintf(hstr, "INTEGER8"); - break; - case ECT_INTEGER16: - sprintf(hstr, "INTEGER16"); - break; - case ECT_INTEGER32: - sprintf(hstr, "INTEGER32"); - break; - case ECT_INTEGER24: - sprintf(hstr, "INTEGER24"); - break; - case ECT_INTEGER64: - sprintf(hstr, "INTEGER64"); - break; - case ECT_UNSIGNED8: - sprintf(hstr, "UNSIGNED8"); - break; - case ECT_UNSIGNED16: - sprintf(hstr, "UNSIGNED16"); - break; - case ECT_UNSIGNED32: - sprintf(hstr, "UNSIGNED32"); - break; - case ECT_UNSIGNED24: - sprintf(hstr, "UNSIGNED24"); - break; - case ECT_UNSIGNED64: - sprintf(hstr, "UNSIGNED64"); - break; - case ECT_REAL32: - sprintf(hstr, "REAL32"); - break; - case ECT_REAL64: - sprintf(hstr, "REAL64"); - break; - case ECT_BIT1: - sprintf(hstr, "BIT1"); - break; - case ECT_BIT2: - sprintf(hstr, "BIT2"); - break; - case ECT_BIT3: - sprintf(hstr, "BIT3"); - break; - case ECT_BIT4: - sprintf(hstr, "BIT4"); - break; - case ECT_BIT5: - sprintf(hstr, "BIT5"); - break; - case ECT_BIT6: - sprintf(hstr, "BIT6"); - break; - case ECT_BIT7: - sprintf(hstr, "BIT7"); - break; - case ECT_BIT8: - sprintf(hstr, "BIT8"); - break; - case ECT_VISIBLE_STRING: - sprintf(hstr, "VISIBLE_STRING"); - break; - case ECT_OCTET_STRING: - sprintf(hstr, "OCTET_STRING"); - break; - default: - sprintf(hstr, "Type 0x%4.4X", dtype); - } - return hstr; -} - -char *SDO2string(uint16 slave, uint16 index, uint8 subidx, uint16 dtype) -{ - int l = sizeof(usdo) - 1, i; - uint8 *u8; - int8 *i8; - uint16 *u16; - int16 *i16; - uint32 *u32; - int32 *i32; - uint64 *u64; - int64 *i64; - float *sr; - double *dr; - char es[32]; - - memset(&usdo, 0, 128); - ec_SDOread(slave, index, subidx, FALSE, &l, &usdo, EC_TIMEOUTRXM); - if (EcatError) - { - return ec_elist2string(); - } - else - { - switch (dtype) - { - case ECT_BOOLEAN: - u8 = (uint8 *)&usdo[0]; - if (*u8) - sprintf(hstr, "TRUE"); - else - sprintf(hstr, "FALSE"); - break; - case ECT_INTEGER8: - i8 = (int8 *)&usdo[0]; - sprintf(hstr, "0x%2.2x %d", *i8, *i8); - break; - case ECT_INTEGER16: - i16 = (int16 *)&usdo[0]; - sprintf(hstr, "0x%4.4x %d", *i16, *i16); - break; - case ECT_INTEGER32: - case ECT_INTEGER24: - i32 = (int32 *)&usdo[0]; - sprintf(hstr, "0x%8.8x %d", *i32, *i32); - break; - case ECT_INTEGER64: - i64 = (int64 *)&usdo[0]; - sprintf(hstr, "0x%16.16" PRIx64 " %" PRId64, *i64, *i64); - break; - case ECT_UNSIGNED8: - u8 = (uint8 *)&usdo[0]; - sprintf(hstr, "0x%2.2x %u", *u8, *u8); - break; - case ECT_UNSIGNED16: - u16 = (uint16 *)&usdo[0]; - sprintf(hstr, "0x%4.4x %u", *u16, *u16); - break; - case ECT_UNSIGNED32: - case ECT_UNSIGNED24: - u32 = (uint32 *)&usdo[0]; - sprintf(hstr, "0x%8.8x %u", *u32, *u32); - break; - case ECT_UNSIGNED64: - u64 = (uint64 *)&usdo[0]; - sprintf(hstr, "0x%16.16" PRIx64 " %" PRIu64, *u64, *u64); - break; - case ECT_REAL32: - sr = (float *)&usdo[0]; - sprintf(hstr, "%f", *sr); - break; - case ECT_REAL64: - dr = (double *)&usdo[0]; - sprintf(hstr, "%f", *dr); - break; - case ECT_BIT1: - case ECT_BIT2: - case ECT_BIT3: - case ECT_BIT4: - case ECT_BIT5: - case ECT_BIT6: - case ECT_BIT7: - case ECT_BIT8: - u8 = (uint8 *)&usdo[0]; - sprintf(hstr, "0x%x", *u8); - break; - case ECT_VISIBLE_STRING: - strcpy(hstr, usdo); - break; - case ECT_OCTET_STRING: - hstr[0] = 0x00; - for (i = 0; i < l; i++) - { - sprintf(es, "0x%2.2x ", usdo[i]); - strcat(hstr, es); - } - break; - default: - sprintf(hstr, "Unknown type"); - } - return hstr; - } -} - -/** Read PDO assign structure */ -int si_PDOassign(uint16 slave, uint16 PDOassign, int mapoffset, int bitoffset) -{ - uint16 idxloop, nidx, subidxloop, rdat, idx, subidx; - uint8 subcnt; - int wkc, bsize = 0, rdl; - int32 rdat2; - uint8 bitlen, obj_subidx; - uint16 obj_idx; - int abs_offset, abs_bit; - - rdl = sizeof(rdat); - rdat = 0; - /* read PDO assign subindex 0 ( = number of PDO's) */ - wkc = ec_SDOread(slave, PDOassign, 0x00, FALSE, &rdl, &rdat, EC_TIMEOUTRXM); - rdat = etohs(rdat); - /* positive result from slave ? */ - if ((wkc > 0) && (rdat > 0)) - { - /* number of available sub indexes */ - nidx = rdat; - bsize = 0; - /* read all PDO's */ - for (idxloop = 1; idxloop <= nidx; idxloop++) - { - rdl = sizeof(rdat); - rdat = 0; - /* read PDO assign */ - wkc = ec_SDOread(slave, PDOassign, (uint8)idxloop, FALSE, &rdl, &rdat, EC_TIMEOUTRXM); - /* result is index of PDO */ - idx = etohl(rdat); - if (idx > 0) - { - rdl = sizeof(subcnt); - subcnt = 0; - /* read number of subindexes of PDO */ - wkc = ec_SDOread(slave, idx, 0x00, FALSE, &rdl, &subcnt, EC_TIMEOUTRXM); - subidx = subcnt; - /* for each subindex */ - for (subidxloop = 1; subidxloop <= subidx; subidxloop++) - { - rdl = sizeof(rdat2); - rdat2 = 0; - /* read SDO that is mapped in PDO */ - wkc = ec_SDOread(slave, idx, (uint8)subidxloop, FALSE, &rdl, &rdat2, EC_TIMEOUTRXM); - rdat2 = etohl(rdat2); - /* extract bitlength of SDO */ - bitlen = LO_BYTE(rdat2); - bsize += bitlen; - obj_idx = (uint16)(rdat2 >> 16); - obj_subidx = (uint8)((rdat2 >> 8) & 0x000000ff); - abs_offset = mapoffset + (bitoffset / 8); - abs_bit = bitoffset % 8; - ODlist.Slave = slave; - ODlist.Index[0] = obj_idx; - OElist.Entries = 0; - wkc = 0; - /* read object entry from dictionary if not a filler (0x0000:0x00) */ - if (obj_idx || obj_subidx) - wkc = ec_readOEsingle(0, obj_subidx, &ODlist, &OElist); - printf(" [0x%4.4X.%1d] 0x%4.4X:0x%2.2X 0x%2.2X", abs_offset, abs_bit, obj_idx, obj_subidx, bitlen); - if ((wkc > 0) && OElist.Entries) - { - printf(" %-12s %s\n", dtype2string(OElist.DataType[obj_subidx]), OElist.Name[obj_subidx]); - } - else - printf("\n"); - bitoffset += bitlen; - }; - }; - }; - }; - /* return total found bitlength (PDO) */ - return bsize; -} - -int si_map_sdo(int slave) -{ - int wkc, rdl; - int retVal = 0; - uint8 nSM, iSM, tSM; - int Tsize, outputs_bo, inputs_bo; - uint8 SMt_bug_add; - - printf("PDO mapping according to CoE :\n"); - SMt_bug_add = 0; - outputs_bo = 0; - inputs_bo = 0; - rdl = sizeof(nSM); - nSM = 0; - /* read SyncManager Communication Type object count */ - wkc = ec_SDOread(slave, ECT_SDO_SMCOMMTYPE, 0x00, FALSE, &rdl, &nSM, EC_TIMEOUTRXM); - /* positive result from slave ? */ - if ((wkc > 0) && (nSM > 2)) - { - /* make nSM equal to number of defined SM */ - nSM--; - /* limit to maximum number of SM defined, if true the slave can't be configured */ - if (nSM > EC_MAXSM) - nSM = EC_MAXSM; - /* iterate for every SM type defined */ - for (iSM = 2; iSM <= nSM; iSM++) - { - rdl = sizeof(tSM); - tSM = 0; - /* read SyncManager Communication Type */ - wkc = ec_SDOread(slave, ECT_SDO_SMCOMMTYPE, iSM + 1, FALSE, &rdl, &tSM, EC_TIMEOUTRXM); - if (wkc > 0) - { - if ((iSM == 2) && (tSM == 2)) // SM2 has type 2 == mailbox out, this is a bug in the slave! - { - SMt_bug_add = 1; // try to correct, this works if the types are 0 1 2 3 and should be 1 2 3 4 - printf("Activated SM type workaround, possible incorrect mapping.\n"); - } - if (tSM) - tSM += SMt_bug_add; // only add if SMt > 0 - - if (tSM == 3) // outputs - { - /* read the assign RXPDO */ - printf(" SM%1d outputs\n addr b index: sub bitl data_type name\n", iSM); - Tsize = si_PDOassign(slave, ECT_SDO_PDOASSIGN + iSM, (int)(ec_slave[slave].outputs - (uint8 *)&IOmap[0]), outputs_bo); - outputs_bo += Tsize; - } - if (tSM == 4) // inputs - { - /* read the assign TXPDO */ - printf(" SM%1d inputs\n addr b index: sub bitl data_type name\n", iSM); - Tsize = si_PDOassign(slave, ECT_SDO_PDOASSIGN + iSM, (int)(ec_slave[slave].inputs - (uint8 *)&IOmap[0]), inputs_bo); - inputs_bo += Tsize; - } - } - } - } - - /* found some I/O bits ? */ - if ((outputs_bo > 0) || (inputs_bo > 0)) - retVal = 1; - return retVal; -} - -int si_siiPDO(uint16 slave, uint8 t, int mapoffset, int bitoffset) -{ - uint16 a, w, c, e, er, Size; - uint8 eectl; - uint16 obj_idx; - uint8 obj_subidx; - uint8 obj_name; - uint8 obj_datatype; - uint8 bitlen; - int totalsize; - ec_eepromPDOt eepPDO; - ec_eepromPDOt *PDO; - int abs_offset, abs_bit; - char str_name[EC_MAXNAME + 1]; - - eectl = ec_slave[slave].eep_pdi; - Size = 0; - totalsize = 0; - PDO = &eepPDO; - PDO->nPDO = 0; - PDO->Length = 0; - PDO->Index[1] = 0; - for (c = 0; c < EC_MAXSM; c++) - PDO->SMbitsize[c] = 0; - if (t > 1) - t = 1; - PDO->Startpos = ec_siifind(slave, ECT_SII_PDO + t); - if (PDO->Startpos > 0) - { - a = PDO->Startpos; - w = ec_siigetbyte(slave, a++); - w += (ec_siigetbyte(slave, a++) << 8); - PDO->Length = w; - c = 1; - /* traverse through all PDOs */ - do - { - PDO->nPDO++; - PDO->Index[PDO->nPDO] = ec_siigetbyte(slave, a++); - PDO->Index[PDO->nPDO] += (ec_siigetbyte(slave, a++) << 8); - PDO->BitSize[PDO->nPDO] = 0; - c++; - /* number of entries in PDO */ - e = ec_siigetbyte(slave, a++); - PDO->SyncM[PDO->nPDO] = ec_siigetbyte(slave, a++); - a++; - obj_name = ec_siigetbyte(slave, a++); - a += 2; - c += 2; - if (PDO->SyncM[PDO->nPDO] < EC_MAXSM) /* active and in range SM? */ - { - str_name[0] = 0; - if (obj_name) - ec_siistring(str_name, slave, obj_name); - if (t) - printf(" SM%1d RXPDO 0x%4.4X %s\n", PDO->SyncM[PDO->nPDO], PDO->Index[PDO->nPDO], str_name); - else - printf(" SM%1d TXPDO 0x%4.4X %s\n", PDO->SyncM[PDO->nPDO], PDO->Index[PDO->nPDO], str_name); - printf(" addr b index: sub bitl data_type name\n"); - /* read all entries defined in PDO */ - for (er = 1; er <= e; er++) - { - c += 4; - obj_idx = ec_siigetbyte(slave, a++); - obj_idx += (ec_siigetbyte(slave, a++) << 8); - obj_subidx = ec_siigetbyte(slave, a++); - obj_name = ec_siigetbyte(slave, a++); - obj_datatype = ec_siigetbyte(slave, a++); - bitlen = ec_siigetbyte(slave, a++); - abs_offset = mapoffset + (bitoffset / 8); - abs_bit = bitoffset % 8; - - PDO->BitSize[PDO->nPDO] += bitlen; - a += 2; - - str_name[0] = 0; - if (obj_name) - ec_siistring(str_name, slave, obj_name); - - printf(" [0x%4.4X.%1d] 0x%4.4X:0x%2.2X 0x%2.2X", abs_offset, abs_bit, obj_idx, obj_subidx, bitlen); - printf(" %-12s %s\n", dtype2string(obj_datatype), str_name); - bitoffset += bitlen; - totalsize += bitlen; - } - PDO->SMbitsize[PDO->SyncM[PDO->nPDO]] += PDO->BitSize[PDO->nPDO]; - Size += PDO->BitSize[PDO->nPDO]; - c++; - } - else /* PDO deactivated because SM is 0xff or > EC_MAXSM */ - { - c += 4 * e; - a += 8 * e; - c++; - } - if (PDO->nPDO >= (EC_MAXEEPDO - 1)) c = PDO->Length; /* limit number of PDO entries in buffer */ - } while (c < PDO->Length); - } - if (eectl) ec_eeprom2pdi(slave); /* if eeprom control was previously pdi then restore */ - return totalsize; -} - -int si_map_sii(int slave) -{ - int retVal = 0; - int Tsize, outputs_bo, inputs_bo; - - printf("PDO mapping according to SII :\n"); - - outputs_bo = 0; - inputs_bo = 0; - /* read the assign RXPDOs */ - Tsize = si_siiPDO(slave, 1, (int)(ec_slave[slave].outputs - (uint8 *)&IOmap), outputs_bo); - outputs_bo += Tsize; - /* read the assign TXPDOs */ - Tsize = si_siiPDO(slave, 0, (int)(ec_slave[slave].inputs - (uint8 *)&IOmap), inputs_bo); - inputs_bo += Tsize; - /* found some I/O bits ? */ - if ((outputs_bo > 0) || (inputs_bo > 0)) - retVal = 1; - return retVal; -} - -void si_sdo(int cnt) -{ - int i, j; - - ODlist.Entries = 0; - memset(&ODlist, 0, sizeof(ODlist)); - if (ec_readODlist(cnt, &ODlist)) - { - printf(" CoE Object Description found, %d entries.\n", ODlist.Entries); - for (i = 0; i < ODlist.Entries; i++) - { - ec_readODdescription(i, &ODlist); - while (EcatError) - printf("%s", ec_elist2string()); - printf(" Index: %4.4x Datatype: %4.4x Objectcode: %2.2x Name: %s\n", - ODlist.Index[i], ODlist.DataType[i], ODlist.ObjectCode[i], ODlist.Name[i]); - memset(&OElist, 0, sizeof(OElist)); - ec_readOE(i, &ODlist, &OElist); - while (EcatError) - printf("%s", ec_elist2string()); - for (j = 0; j < ODlist.MaxSub[i] + 1; j++) - { - if ((OElist.DataType[j] > 0) && (OElist.BitLength[j] > 0)) - { - printf(" Sub: %2.2x Datatype: %4.4x Bitlength: %4.4x Obj.access: %4.4x Name: %s\n", - j, OElist.DataType[j], OElist.BitLength[j], OElist.ObjAccess[j], OElist.Name[j]); - if ((OElist.ObjAccess[j] & 0x0007)) - { - printf(" Value :%s\n", SDO2string(cnt, ODlist.Index[i], j, OElist.DataType[j])); - } - } - } - } - } - else - { - while (EcatError) - printf("%s", ec_elist2string()); - } -} - -void slaveinfo(char *ifname) -{ - int cnt, i, j, nSM; - uint16 ssigen; - int expectedWKC; - - printf("Starting slaveinfo\n"); - - /* initialise SOEM, bind socket to ifname */ - if (ec_init(ifname)) - { - printf("ec_init on %s succeeded.\n", ifname); - /* find and auto-config slaves */ - if (ec_config(FALSE, &IOmap) > 0) - { - ec_configdc(); - while (EcatError) - printf("%s", ec_elist2string()); - printf("%d slaves found and configured.\n", ec_slavecount); - expectedWKC = (ec_group[0].outputsWKC * 2) + ec_group[0].inputsWKC; - printf("Calculated workcounter %d\n", expectedWKC); - /* wait for all slaves to reach SAFE_OP state */ - ec_statecheck(0, EC_STATE_SAFE_OP, EC_TIMEOUTSTATE * 3); - if (ec_slave[0].state != EC_STATE_SAFE_OP) - { - printf("Not all slaves reached safe operational state.\n"); - ec_readstate(); - for (i = 1; i <= ec_slavecount; i++) - { - if (ec_slave[i].state != EC_STATE_SAFE_OP) - { - printf("Slave %d State=%2x StatusCode=%4x : %s\n", - i, ec_slave[i].state, ec_slave[i].ALstatuscode, ec_ALstatuscode2string(ec_slave[i].ALstatuscode)); - } - } - } - - ec_readstate(); - for (cnt = 1; cnt <= ec_slavecount; cnt++) - { - printf("\nSlave:%d\n Name:%s\n Output size: %dbits\n Input size: %dbits\n State: %d\n Delay: %d[ns]\n Has DC: %d\n", - cnt, ec_slave[cnt].name, ec_slave[cnt].Obits, ec_slave[cnt].Ibits, - ec_slave[cnt].state, ec_slave[cnt].pdelay, ec_slave[cnt].hasdc); - if (ec_slave[cnt].hasdc) printf(" DCParentport:%d\n", ec_slave[cnt].parentport); - printf(" Activeports:%d.%d.%d.%d\n", (ec_slave[cnt].activeports & 0x01) > 0, - (ec_slave[cnt].activeports & 0x02) > 0, - (ec_slave[cnt].activeports & 0x04) > 0, - (ec_slave[cnt].activeports & 0x08) > 0); - printf(" Configured address: %4.4x\n", ec_slave[cnt].configadr); - printf(" Man: %8.8x ID: %8.8x Rev: %8.8x\n", (int)ec_slave[cnt].eep_man, (int)ec_slave[cnt].eep_id, (int)ec_slave[cnt].eep_rev); - for (nSM = 0; nSM < EC_MAXSM; nSM++) - { - if (ec_slave[cnt].SM[nSM].StartAddr > 0) - printf(" SM%1d A:%4.4x L:%4d F:%8.8x Type:%d\n", nSM, ec_slave[cnt].SM[nSM].StartAddr, ec_slave[cnt].SM[nSM].SMlength, - (int)ec_slave[cnt].SM[nSM].SMflags, ec_slave[cnt].SMtype[nSM]); - } - for (j = 0; j < ec_slave[cnt].FMMUunused; j++) - { - printf(" FMMU%1d Ls:%8.8x Ll:%4d Lsb:%d Leb:%d Ps:%4.4x Psb:%d Ty:%2.2x Act:%2.2x\n", j, - (int)ec_slave[cnt].FMMU[j].LogStart, ec_slave[cnt].FMMU[j].LogLength, ec_slave[cnt].FMMU[j].LogStartbit, - ec_slave[cnt].FMMU[j].LogEndbit, ec_slave[cnt].FMMU[j].PhysStart, ec_slave[cnt].FMMU[j].PhysStartBit, - ec_slave[cnt].FMMU[j].FMMUtype, ec_slave[cnt].FMMU[j].FMMUactive); - } - printf(" FMMUfunc 0:%d 1:%d 2:%d 3:%d\n", - ec_slave[cnt].FMMU0func, ec_slave[cnt].FMMU1func, ec_slave[cnt].FMMU2func, ec_slave[cnt].FMMU3func); - printf(" MBX length wr: %d rd: %d MBX protocols : %2.2x\n", ec_slave[cnt].mbx_l, ec_slave[cnt].mbx_rl, ec_slave[cnt].mbx_proto); - ssigen = ec_siifind(cnt, ECT_SII_GENERAL); - /* SII general section */ - if (ssigen) - { - ec_slave[cnt].CoEdetails = ec_siigetbyte(cnt, ssigen + 0x07); - ec_slave[cnt].FoEdetails = ec_siigetbyte(cnt, ssigen + 0x08); - ec_slave[cnt].EoEdetails = ec_siigetbyte(cnt, ssigen + 0x09); - ec_slave[cnt].SoEdetails = ec_siigetbyte(cnt, ssigen + 0x0a); - if ((ec_siigetbyte(cnt, ssigen + 0x0d) & 0x02) > 0) - { - ec_slave[cnt].blockLRW = 1; - ec_slave[0].blockLRW++; - } - ec_slave[cnt].Ebuscurrent = ec_siigetbyte(cnt, ssigen + 0x0e); - ec_slave[cnt].Ebuscurrent += ec_siigetbyte(cnt, ssigen + 0x0f) << 8; - ec_slave[0].Ebuscurrent += ec_slave[cnt].Ebuscurrent; - } - printf(" CoE details: %2.2x FoE details: %2.2x EoE details: %2.2x SoE details: %2.2x\n", - ec_slave[cnt].CoEdetails, ec_slave[cnt].FoEdetails, ec_slave[cnt].EoEdetails, ec_slave[cnt].SoEdetails); - printf(" Ebus current: %d[mA]\n only LRD/LWR:%d\n", - ec_slave[cnt].Ebuscurrent, ec_slave[cnt].blockLRW); - if ((ec_slave[cnt].mbx_proto & ECT_MBXPROT_COE) && printSDO) - si_sdo(cnt); - if (printMAP) - { - if (ec_slave[cnt].mbx_proto & ECT_MBXPROT_COE) - si_map_sdo(cnt); - else - si_map_sii(cnt); - } - } - } - else - { - printf("No slaves found!\n"); - } - printf("End slaveinfo, close socket\n"); - /* stop SOEM, close socket */ - ec_close(); - } - else - { - printf("No socket connection on %s\nExcecute as root\n", ifname); - } -} - -char ifbuf[1024]; - -int main(int argc, char *argv[]) -{ - ec_adaptert *adapter = NULL; - ec_adaptert *head = NULL; - printf("SOEM (Simple Open EtherCAT Master)\nSlaveinfo\n"); - - if (argc > 1) - { - if ((argc > 2) && (strncmp(argv[2], "-sdo", sizeof("-sdo")) == 0)) printSDO = TRUE; - if ((argc > 2) && (strncmp(argv[2], "-map", sizeof("-map")) == 0)) printMAP = TRUE; - /* start slaveinfo */ - strcpy(ifbuf, argv[1]); - slaveinfo(ifbuf); - } - else - { - printf("Usage: slaveinfo ifname [options]\nifname = eth0 for example\nOptions :\n -sdo : print SDO info\n -map : print mapping\n"); - /* Print the list */ - printf("Available adapters\n"); - head = adapter = ec_find_adapters(); - while (adapter != NULL) - { - printf("Description : %s, Device to use for wpcap: %s\n", adapter->desc, adapter->name); - adapter = adapter->next; - } - ec_free_adapters(head); - } - - printf("End program\n"); - return (0); -}