Added slaveinfo sample for circle.

pull/289/head
Davide Pippa 2019-04-30 14:31:43 +02:00
parent a448749ff7
commit 7e2ad64b33
5 changed files with 864 additions and 0 deletions

View File

@ -0,0 +1,2 @@
*.o
kernel8*

View File

@ -0,0 +1,27 @@
#
# Makefile
#
CIRCLEHOME = ../../../libs/circle-stdlib/libs/circle
NEWLIBDIR = ../../../libs/circle-stdlib/install/arm-none-circle
SOEMBUILDDIR = ../../../build
SOEMSRCDIR = ../../../
OBJS = main.o kernel.o
include $(CIRCLEHOME)/Rules.mk
CFLAGS += -I "$(NEWLIBDIR)/include" -I $(STDDEF_INCPATH) \
-I $(SOEMSRCDIR)/soem \
-I $(SOEMSRCDIR)/osal -I $(SOEMSRCDIR)/osal/circle \
-I $(SOEMSRCDIR)/oshw -I $(SOEMSRCDIR)/oshw/circle
LIBS := $(SOEMBUILDDIR)/libsoem.a \
"$(NEWLIBDIR)/lib/libm.a" "$(NEWLIBDIR)/lib/libc.a" "$(NEWLIBDIR)/lib/libcirclenewlib.a" \
$(CIRCLEHOME)/addon/SDCard/libsdcard.a \
$(CIRCLEHOME)/lib/usb/libusb.a \
$(CIRCLEHOME)/lib/input/libinput.a \
$(CIRCLEHOME)/lib/fs/fat/libfatfs.a \
$(CIRCLEHOME)/lib/fs/libfs.a \
$(CIRCLEHOME)/lib/net/libnet.a \
$(CIRCLEHOME)/lib/sched/libsched.a \
$(CIRCLEHOME)/lib/libcircle.a

View File

@ -0,0 +1,724 @@
//
// kernel.cpp
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
#include "kernel.h"
#include <circle/usb/usb.h>
#include <circle/usb/netdevice.h>
#include <circle/usb/macaddress.h>
#include <circle/string.h>
#include <circle/macros.h>
#include <circle/debug.h>
#include <assert.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#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;
/* skip entry if filler (0x0000:0x00) */
if(obj_idx || obj_subidx)
{
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(const 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];
namespace
{
char const FromKernel[] = "kernel";
}
CKernel::CKernel (void)
: m_Screen (m_Options.GetWidth (), m_Options.GetHeight ()),
m_Timer (&m_Interrupt),
m_Logger (m_Options.GetLogLevel (), &m_Timer),
m_DWHCI (&m_Interrupt, &m_Timer)
{
m_ActLED.Blink (5); // show we are alive
}
CKernel::~CKernel (void)
{
}
boolean CKernel::Initialize (void)
{
boolean bOK = TRUE;
if (bOK)
{
bOK = m_Screen.Initialize ();
}
if (bOK)
{
bOK = m_Serial.Initialize (115200);
}
if (bOK)
{
CDevice *pTarget = m_DeviceNameService.GetDevice (m_Options.GetLogDevice (), FALSE);
if (pTarget == 0)
{
pTarget = &m_Screen;
}
bOK = m_Logger.Initialize (pTarget);
}
if (bOK)
{
bOK = m_Interrupt.Initialize ();
}
if (bOK)
{
bOK = m_Timer.Initialize ();
}
if (bOK)
{
bOK = m_DWHCI.Initialize ();
}
return bOK;
}
TShutdownMode CKernel::Run (void)
{
m_Logger.Write (FromKernel, LogNotice, "Compile time: " __DATE__ " " __TIME__);
CNetDevice *pEth0 = (CNetDevice *) m_DeviceNameService.GetDevice ("eth0", FALSE);
if (pEth0 == 0)
{
m_Logger.Write (FromKernel, LogError, "Net device not found");
return ShutdownHalt;
}
// wait for Ethernet PHY to come up
m_Timer.MsDelay (2000);
m_Logger.Write (FromKernel, LogNotice, "EtherCAT Master Demo");
printSDO = TRUE;
printMAP = TRUE;
slaveinfo("eth0");
m_Logger.Write (FromKernel, LogNotice, "EtherCAT Master Demo finished");
return ShutdownHalt;
}

View File

@ -0,0 +1,67 @@
//
// kernel.h
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
#ifndef _kernel_h
#define _kernel_h
#include <circle/memory.h>
#include <circle/actled.h>
#include <circle/koptions.h>
#include <circle/devicenameservice.h>
#include <circle/screen.h>
#include <circle/serial.h>
#include <circle/exceptionhandler.h>
#include <circle/interrupt.h>
#include <circle/timer.h>
#include <circle/logger.h>
#include <circle/usb/dwhcidevice.h>
#include <circle/types.h>
enum TShutdownMode
{
ShutdownNone,
ShutdownHalt,
ShutdownReboot
};
class CKernel
{
public:
CKernel (void);
~CKernel (void);
boolean Initialize (void);
TShutdownMode Run (void);
private:
// do not change this order
CMemorySystem m_Memory;
CActLED m_ActLED;
CKernelOptions m_Options;
CDeviceNameService m_DeviceNameService;
CScreenDevice m_Screen;
CSerialDevice m_Serial;
CExceptionHandler m_ExceptionHandler;
CInterruptSystem m_Interrupt;
CTimer m_Timer;
CLogger m_Logger;
CDWHCIDevice m_DWHCI;
};
#endif

View File

@ -0,0 +1,44 @@
//
// main.c
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
#include "kernel.h"
#include <circle/startup.h>
int main (void)
{
// cannot return here because some destructors used in CKernel are not implemented
CKernel Kernel;
if (!Kernel.Initialize ())
{
halt ();
return EXIT_HALT;
}
TShutdownMode ShutdownMode = Kernel.Run ();
switch (ShutdownMode)
{
case ShutdownReboot:
reboot ();
return EXIT_REBOOT;
case ShutdownHalt:
default:
halt ();
return EXIT_HALT;
}
}