/** SoE write, blocking.
 * 
 * The IDN object of the selected slave and DriveNo is written. If a response
 * is larger than the mailbox size then the response is segmented.
 *
 * @param[in]  slave		= Slave number
 * @param[in]  driveNo		= Drive number in slave
 * @param[in]  elementflags = Flags to select what properties of IDN are to be transfered.
 * @param[in]  idn			= IDN.
 * @param[in]  psize		= Size in bytes of parameter buffer.
 * @param[out] p			= Pointer to parameter buffer
 * @param[in]  timeout		= Timeout in us, standard is EC_TIMEOUTRXM
 * @return Workcounter from last slave response
 */
int ec_SoEwrite(uint16 slave, uint8 driveNo, uint8 elementflags, uint16 idn, int psize, void *p, int timeout)
{
    ec_SoEt *SoEp, *aSoEp;
    uint16 framedatasize, maxdata;
	int wkc;
    uint8 *mp;
	uint8 *hp;
	uint16 *errorcode;
    ec_mbxbuft MbxIn, MbxOut;
    uint8 cnt;
	boolean NotLast;

    ec_clearmbx(&MbxIn);
	/* Empty slave out mailbox if something is in. Timeout set to 0 */
    wkc = ec_mbxreceive(slave, (ec_mbxbuft *)&MbxIn, 0);
    ec_clearmbx(&MbxOut);
    aSoEp = (ec_SoEt *)&MbxIn;
    SoEp = (ec_SoEt *)&MbxOut;
    SoEp->MbxHeader.address = htoes(0x0000);
    SoEp->MbxHeader.priority = 0x00;
	SoEp->opCode = ECT_SOE_WRITEREQ;
	SoEp->error = 0;
	SoEp->driveNo = driveNo;
	SoEp->elementflags = elementflags;
	hp = p;
	mp = (uint8 *)&MbxOut + sizeof(ec_SoEt);
    maxdata = ec_slave[slave].mbx_l - sizeof(ec_SoEt);
	NotLast = TRUE;
	while (NotLast)
	{	
		framedatasize = psize;
		NotLast = FALSE;
		SoEp->idn = htoes(idn);
		SoEp->incomplete = 0;
		if (framedatasize > maxdata)
		{
			framedatasize = maxdata;  /*  segmented transfer needed  */
			NotLast = TRUE;
			SoEp->incomplete = 1;
			SoEp->fragmentsleft = psize / maxdata;
		}
		SoEp->MbxHeader.length = htoes(sizeof(ec_SoEt) - sizeof(ec_mbxheadert) + framedatasize);
		/* get new mailbox counter, used for session handle */
		cnt = ec_nextmbxcnt(ec_slave[slave].mbx_cnt);
		ec_slave[slave].mbx_cnt = cnt;
		SoEp->MbxHeader.mbxtype = ECT_MBXT_SOE + (cnt << 4); /* SoE */
		/* copy parameter data to mailbox */
		memcpy(mp, hp, framedatasize);
		hp += framedatasize;
		psize -= framedatasize;
		/* send SoE request to slave */
		wkc = ec_mbxsend(slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
		if (wkc > 0) /* succeeded to place mailbox in slave ? */
		{
			if (!NotLast || !ec_mbxempty(slave, timeout))
			{	
				/* clean mailboxbuffer */
				ec_clearmbx(&MbxIn);
				/* read slave response */
				wkc = ec_mbxreceive(slave, (ec_mbxbuft *)&MbxIn, timeout);
				if (wkc > 0) /* succeeded to read slave response ? */
				{
					NotLast = FALSE;
					/* slave response should be SoE, WriteRes */
					if (((aSoEp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_SOE) &&
					    (aSoEp->opCode == ECT_SOE_WRITERES) &&
					    (aSoEp->error == 0) &&
					    (aSoEp->driveNo == driveNo) &&
					    (aSoEp->elementflags == elementflags))
					{
						/* SoE write succeeded */
					}	
					/* other slave response */
					else
					{
						if (((aSoEp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_SOE) &&
						    (aSoEp->opCode == ECT_SOE_READRES) &&
						    (aSoEp->error == 1))
						{
							mp = (uint8 *)&MbxIn + (etohs(aSoEp->MbxHeader.length) + sizeof(ec_mbxheadert) - sizeof(uint16));
							errorcode = (uint16 *)mp;
							ec_SoEerror(slave, idn, *errorcode);
						}
						else
						{
							ec_packeterror(slave, idn, 0, 1); /* Unexpected frame returned */
						}
						wkc = 0;
					}
				}
				else
				{
					ec_packeterror(slave, idn, 0, 4); /* no response */
				}	
			}	
		}	
	}
    return wkc;
}
Beispiel #2
0
/** FoE read, blocking.
 * 
 * @param[in]  slave		= Slave number.
 * @param[in]  filename		= Filename of file to read.
 * @param[in]  password     = password.
 * @param[in,out] psize		= Size in bytes of file buffer, returns bytes read from file.
 * @param[out] p			= Pointer to file buffer
 * @param[in]  timeout		= Timeout in us, standard is EC_TIMEOUTRXM
 * @return Workcounter from last slave response
 */
int ec_FOEread(uint16 slave, char *filename, uint32 password, int *psize, void *p, int timeout)
{
    ec_FOEt *FOEp, *aFOEp;
	int wkc;
    int32 dataread = 0;
	int32 buffersize, packetnumber, prevpacket = 0;
	uint16 fnsize, maxdata, segmentdata;
    ec_mbxbuft MbxIn, MbxOut;
    uint8 cnt;
    boolean worktodo;

	buffersize = *psize;
    ec_clearmbx(&MbxIn);
	/* Empty slave out mailbox if something is in. Timout set to 0 */
    wkc = ec_mbxreceive(slave, (ec_mbxbuft *)&MbxIn, 0);
    ec_clearmbx(&MbxOut);
    aFOEp = (ec_FOEt *)&MbxIn;
    FOEp = (ec_FOEt *)&MbxOut;
	fnsize = strlen(filename);
	maxdata = ec_slave[slave].mbx_l - 12;
	if (fnsize > maxdata)
		fnsize = maxdata;
    FOEp->MbxHeader.length = htoes(0x0006 + fnsize);
    FOEp->MbxHeader.address = htoes(0x0000);
    FOEp->MbxHeader.priority = 0x00;
	/* get new mailbox count value, used as session handle */
    cnt = ec_nextmbxcnt(ec_slave[slave].mbx_cnt);
    ec_slave[slave].mbx_cnt = cnt;
    FOEp->MbxHeader.mbxtype = ECT_MBXT_FOE + (cnt << 4); /* FoE */
    FOEp->OpCode = ECT_FOE_READ;
    FOEp->Password = htoel(password);
	/* copy filename in mailbox */
	memcpy(&FOEp->FileName[0], filename, fnsize);
	/* send FoE request to slave */
    wkc = ec_mbxsend(slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
    if (wkc > 0) /* succeeded to place mailbox in slave ? */
    {
		do
		{	
			worktodo = FALSE;
			/* clean mailboxbuffer */
			ec_clearmbx(&MbxIn);
			/* read slave response */
			wkc = ec_mbxreceive(slave, (ec_mbxbuft *)&MbxIn, timeout);
			if (wkc > 0) /* succeeded to read slave response ? */
			{
				/* slave response should be FoE */
				if ((aFOEp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_FOE)
				{
					if(aFOEp->OpCode == ECT_FOE_DATA)
					{
						segmentdata = etohs(aFOEp->MbxHeader.length) - 0x0006;
						packetnumber = etohl(aFOEp->PacketNumber);
						if ((packetnumber == ++prevpacket) && (dataread + segmentdata <= buffersize))
						{
							memcpy(p, &aFOEp->Data[0], segmentdata);
							dataread += segmentdata;
							p += segmentdata;
							if (segmentdata == maxdata)
								worktodo = TRUE; 
							FOEp->MbxHeader.length = htoes(0x0006);
							FOEp->MbxHeader.address = htoes(0x0000);
							FOEp->MbxHeader.priority = 0x00;
							/* get new mailbox count value */
							cnt = ec_nextmbxcnt(ec_slave[slave].mbx_cnt);
							ec_slave[slave].mbx_cnt = cnt;
							FOEp->MbxHeader.mbxtype = ECT_MBXT_FOE + (cnt << 4); /* FoE */
							FOEp->OpCode = ECT_FOE_ACK;
							FOEp->PacketNumber = htoel(packetnumber);
							/* send FoE ack to slave */
							wkc = ec_mbxsend(slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
							if (wkc <= 0)
								worktodo = FALSE;
						}
						else
						{
							/* FoE error */
							wkc = -EC_ERR_TYPE_FOE_BUF2SMALL;
						}
					}
					else
					if(aFOEp->OpCode == ECT_FOE_ERROR)
					{
						/* FoE error */
						wkc = -EC_ERR_TYPE_FOE_ERROR;
					}
					else
					{
						/* unexpected mailbox received */
						wkc = -EC_ERR_TYPE_PACKET_ERROR;
					}
				}
				else
				{
					/* unexpected mailbox received */
					wkc = -EC_ERR_TYPE_PACKET_ERROR;
				}
				*psize = dataread;
			}
		} while (worktodo);	
	}
	
	return wkc;
}	
/** SoE read, blocking.
 * 
 * The IDN object of the selected slave and DriveNo is read. If a response
 * is larger than the mailbox size then the response is segmented. The function
 * will combine all segments and copy them to the parameter buffer.
 *
 * @param[in]  slave		= Slave number
 * @param[in]  driveNo		= Drive number in slave
 * @param[in]  elementflags = Flags to select what properties of IDN are to be transfered.
 * @param[in]  idn			= IDN.
 * @param[in,out] psize		= Size in bytes of parameter buffer, returns bytes read from SoE.
 * @param[out] p			= Pointer to parameter buffer
 * @param[in]  timeout		= Timeout in us, standard is EC_TIMEOUTRXM
 * @return Workcounter from last slave response
 */
int ec_SoEread(uint16 slave, uint8 driveNo, uint8 elementflags, uint16 idn, int *psize, void *p, int timeout)
{
    ec_SoEt *SoEp, *aSoEp;
    uint16 totalsize, framedatasize;
	int wkc;
    uint8 *bp;
	uint8 *mp;
	uint16 *errorcode;
    ec_mbxbuft MbxIn, MbxOut;
    uint8 cnt;
	boolean NotLast;

    ec_clearmbx(&MbxIn);
	/* Empty slave out mailbox if something is in. Timeout set to 0 */
    wkc = ec_mbxreceive(slave, (ec_mbxbuft *)&MbxIn, 0);
    ec_clearmbx(&MbxOut);
    aSoEp = (ec_SoEt *)&MbxIn;
    SoEp = (ec_SoEt *)&MbxOut;
    SoEp->MbxHeader.length = htoes(sizeof(ec_SoEt) - sizeof(ec_mbxheadert));
    SoEp->MbxHeader.address = htoes(0x0000);
    SoEp->MbxHeader.priority = 0x00;
	/* get new mailbox count value, used as session handle */
    cnt = ec_nextmbxcnt(ec_slave[slave].mbx_cnt);
    ec_slave[slave].mbx_cnt = cnt;
    SoEp->MbxHeader.mbxtype = ECT_MBXT_SOE + (cnt << 4); /* SoE */
	SoEp->opCode = ECT_SOE_READREQ;
	SoEp->incomplete = 0;
	SoEp->error = 0;
	SoEp->driveNo = driveNo;
	SoEp->elementflags = elementflags;
	SoEp->idn = htoes(idn);
	totalsize = 0;
	bp = p;
	mp = (uint8 *)&MbxIn + sizeof(ec_SoEt);
	NotLast = TRUE;
	/* send SoE request to slave */
    wkc = ec_mbxsend(slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
    if (wkc > 0) /* succeeded to place mailbox in slave ? */
	{
		while (NotLast)
		{	
			/* clean mailboxbuffer */
			ec_clearmbx(&MbxIn);
			/* read slave response */
			wkc = ec_mbxreceive(slave, (ec_mbxbuft *)&MbxIn, timeout);
			if (wkc > 0) /* succeeded to read slave response ? */
			{
				/* slave response should be SoE, ReadRes */
				if (((aSoEp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_SOE) &&
				    (aSoEp->opCode == ECT_SOE_READRES) &&
				    (aSoEp->error == 0) &&
				    (aSoEp->driveNo == driveNo) &&
				    (aSoEp->elementflags == elementflags))
				{
					framedatasize = etohs(aSoEp->MbxHeader.length) - sizeof(ec_SoEt)  + sizeof(ec_mbxheadert);
					totalsize += framedatasize;
					/* Does parameter fit in parameter buffer ? */
					if (totalsize <= *psize)
					{
						/* copy parameter data in parameter buffer */
						memcpy(bp, mp, framedatasize);
						/* increment buffer pointer */
						bp += framedatasize;
					}
					else
					{
						framedatasize -= totalsize - *psize;
						totalsize = *psize;
						/* copy parameter data in parameter buffer */
						if (framedatasize > 0) memcpy(bp, mp, framedatasize);
					}	

					if (!aSoEp->incomplete)	
					{
						NotLast = FALSE;
						*psize = totalsize;
					}	
				}	
				/* other slave response */
				else
				{
					NotLast = FALSE;
					if (((aSoEp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_SOE) &&
					    (aSoEp->opCode == ECT_SOE_READRES) &&
					    (aSoEp->error == 1))
					{
						mp = (uint8 *)&MbxIn + (etohs(aSoEp->MbxHeader.length) + sizeof(ec_mbxheadert) - sizeof(uint16));
						errorcode = (uint16 *)mp;
						ec_SoEerror(slave, idn, *errorcode);
					}
					else
					{
						ec_packeterror(slave, idn, 0, 1); /* Unexpected frame returned */
					}
					wkc = 0;
				}
			}
			else
			{
				NotLast = FALSE;
				ec_packeterror(slave, idn, 0, 4); /* no response */
			}	
		}	
	}
    return wkc;
}
Beispiel #4
0
/** FoE write, blocking.
 * 
 * @param[in]  context        = context struct
 * @param[in]  slave      = Slave number.
 * @param[in]  filename   = Filename of file to write.
 * @param[in]  password   = password.
 * @param[in]  psize      = Size in bytes of file buffer.
 * @param[out] p          = Pointer to file buffer
 * @param[in]  timeout    = Timeout per mailbox cycle in us, standard is EC_TIMEOUTRXM
 * @return Workcounter from last slave response
 */
int ecx_FOEwrite(ecx_contextt *context, uint16 slave, char *filename, uint32 password, int psize, void *p, int timeout)
{
   ec_FOEt *FOEp, *aFOEp;
   int wkc;
   int32 packetnumber, sendpacket = 0;
   uint16 fnsize, maxdata;
   int segmentdata;
   ec_mbxbuft MbxIn, MbxOut;
   uint8 cnt;
   boolean worktodo, dofinalzero;
   int tsize;

   ec_clearmbx(&MbxIn);
   /* Empty slave out mailbox if something is in. Timout set to 0 */
   wkc = ecx_mbxreceive(context, slave, (ec_mbxbuft *)&MbxIn, 0);
   ec_clearmbx(&MbxOut);
   aFOEp = (ec_FOEt *)&MbxIn;
   FOEp = (ec_FOEt *)&MbxOut;
   dofinalzero = FALSE;
   fnsize = strlen(filename);
   maxdata = context->slavelist[slave].mbx_l - 12;
   if (fnsize > maxdata)
   {
      fnsize = maxdata;
   }
   FOEp->MbxHeader.length = htoes(0x0006 + fnsize);
   FOEp->MbxHeader.address = htoes(0x0000);
   FOEp->MbxHeader.priority = 0x00;
   /* get new mailbox count value, used as session handle */
   cnt = ec_nextmbxcnt(context->slavelist[slave].mbx_cnt);
   context->slavelist[slave].mbx_cnt = cnt;
   FOEp->MbxHeader.mbxtype = ECT_MBXT_FOE + (cnt << 4); /* FoE */
   FOEp->OpCode = ECT_FOE_WRITE;
   FOEp->Password = htoel(password);
   /* copy filename in mailbox */
   memcpy(&FOEp->FileName[0], filename, fnsize);
   /* send FoE request to slave */
   wkc = ecx_mbxsend(context, slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
   if (wkc > 0) /* succeeded to place mailbox in slave ? */
   {
      do
      {   
         worktodo = FALSE;
         /* clean mailboxbuffer */
         ec_clearmbx(&MbxIn);
         /* read slave response */
         wkc = ecx_mbxreceive(context, slave, (ec_mbxbuft *)&MbxIn, timeout);
         if (wkc > 0) /* succeeded to read slave response ? */
         {
            /* slave response should be FoE */
            if ((aFOEp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_FOE)
            {
               switch (aFOEp->OpCode)
               {
                  case ECT_FOE_ACK:
                  {
                     packetnumber = etohl(aFOEp->PacketNumber);
                     if (packetnumber == sendpacket)
                     {
                        if (context->FOEhook)
                        {
                           context->FOEhook(slave, packetnumber, psize);
                        }
                        tsize = psize;
                        if (tsize > maxdata)
                        {
                           tsize = maxdata;
                        }
                        if(tsize || dofinalzero)
                        {
                           worktodo = TRUE; 
                           dofinalzero = FALSE;
                           segmentdata = tsize;
                           psize -= segmentdata;
                           /* if last packet was full size, add a zero size packet as final */
                           /* EOF is defined as packetsize < full packetsize */
                           if (!psize && (segmentdata == maxdata))
                           {
                              dofinalzero = TRUE;
                           }
                           FOEp->MbxHeader.length = htoes(0x0006 + segmentdata);
                           FOEp->MbxHeader.address = htoes(0x0000);
                           FOEp->MbxHeader.priority = 0x00;
                           /* get new mailbox count value */
                           cnt = ec_nextmbxcnt(context->slavelist[slave].mbx_cnt);
                           context->slavelist[slave].mbx_cnt = cnt;
                           FOEp->MbxHeader.mbxtype = ECT_MBXT_FOE + (cnt << 4); /* FoE */
                           FOEp->OpCode = ECT_FOE_DATA;
                           sendpacket++;
                           FOEp->PacketNumber = htoel(sendpacket);
                           memcpy(&FOEp->Data[0], p, segmentdata);
                           p = (uint8 *)p + segmentdata;
                           /* send FoE data to slave */
                           wkc = ecx_mbxsend(context, slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
                           if (wkc <= 0)
                           {   
                              worktodo = FALSE;
                           }
                        }
                     }
                     else
                     {
                        /* FoE error */
                        wkc = -EC_ERR_TYPE_FOE_PACKETNUMBER;
                     }
                     break;
                  }
                  case ECT_FOE_BUSY:
                  {
                     /* resend if data has been send before */
                     /* otherwise ignore */
                     if (sendpacket)
                     {
                        if (!psize)
                        {
                           dofinalzero = TRUE;
                        }
                        psize += segmentdata;
                        p = (uint8 *)p - segmentdata;
                        --sendpacket;
                     }
                     break;
                  }
                  case ECT_FOE_ERROR:
                  {
                     /* FoE error */
                     wkc = -EC_ERR_TYPE_FOE_ERROR;
                     break;
                  }
                  default:
                  {
                     /* unexpected mailbox received */
                     wkc = -EC_ERR_TYPE_PACKET_ERROR;
                     break;
                  }
               }
            }
            else
            {
               /* unexpected mailbox received */
               wkc = -EC_ERR_TYPE_PACKET_ERROR;
            }
         }
      } while (worktodo);   
   }
   
   return wkc;
}