📄 ieee1588.c
字号:
#include "ucos_ii.h"
#include "memif.h"
#define IEEE1588_GLOBALS
#include "ptp_module.h"
#undef IEEE1588_GLOBALS
#include "timer.h"
#include <String.h>
uint8 PTPMACADDR[6]={0x01,0x00,0x5e,0x00,0x01,0x81};
uint8 gLOCALUUID[]={0x00,0x0C,0x76,0xFE,0x33,0x83};
uint32 gPresionToffset = 150000;
#ifdef IEEE1588_CLOCK_MASTER
unsigned long int MasterInterval = 0;
#endif
#if PTP_DEBUG > 0
static LONG test_ns[1][10];
static uint8 ns_count=0;
static LONG Avgnanoseconds = 0;
#endif
#if PTP_AVG_ACC > 0
static unsigned long int Avg = 0;
static unsigned char ucPTPCount = 0;
static BOOL avg_work=0;
#endif
#if DISCARD_EXCEPTION > 0
TimeRepresentation Tsync_expire;
TimeDiff old_offset;
unsigned char Tsync_expireflags = 0;
#endif
static uint8 gPTP_EVENT_MESSAGE[] = {
0x00,0x01,0x00,0x01,0xE0,0x00,0x01,0x81,0xE0,0x00,0x01,0x82,
0xE0,0x00,0x01,0x83,0xE0,0x00,0x01,0x84,0x00,0x01,0x00,0x0C,
0x76,0xFE,0x33,0x83,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0xFF};
#if PTP_TEST_EN > 0
void PtpTestInput(PInSock pisock, TimeRepresentation* Tcurrent){
POutSock posock;
PTPTestFrame* pPTPTestFrame;
PTPRevStampFrame* pPTPRecvFrame;
posock = GetOutSock(PROTOCOL_ETHER);
pPTPTestFrame = (PTPTestFrame*)(pisock->payload);
pPTPRecvFrame = (PTPRevStampFrame*)posock->payload;
#if 0
//修正到主轴附近(sunpan)
Tcurrent->nanoseconds += (55000 - 6000 - 38000);
if(Tcurrent->nanoseconds > 1000000000){
Tcurrent->seconds++;
Tcurrent->nanoseconds -= 1000000000;
}
#endif
pPTPRecvFrame->TestSequenceId = pPTPTestFrame->TestSequenceId;
pPTPRecvFrame->RevTimeStamp.seconds = Tcurrent->seconds;
pPTPRecvFrame->RevTimeStamp.nanoseconds = Tcurrent->nanoseconds;
pPTPRecvFrame->DeviceNum = (char)(gNetIf.localip&0xff);//(uint8 )(my_ipaddr&0xFF);
pPTPRecvFrame->Version = 0x00;
memcpy(pPTPRecvFrame, pisock->payload + 6 ,6);
FreeInSock(pisock);
memcpy((uint8*)(pPTPRecvFrame) + 6, gNetIf.macaddr, 6);
pPTPRecvFrame->wfProtocol = PTP_TESTRECVFRAME_TYPE;
posock->length = sizeof(PTPRevStampFrame);
gNetIf.output(posock);
//send_frame(sSB,sizeof(PTPRevStampFrame));
}
#endif // PTP_TEST_EN
unsigned short int EXCHANGEU16(unsigned short int tempt)
{
unsigned short int U16Tempt = tempt;
U16Tempt = U16Tempt >> 8 | U16Tempt << 8 ;
return U16Tempt;
}
void INT32UCOPY(uint32 * pVaule,uint32 *pResult)
{
Octet *U32Tempt1;
Octet U32Tempt2[4];
U32Tempt1 = (Octet*)pVaule;
U32Tempt2[0] = U32Tempt1[0];
U32Tempt2[1] = U32Tempt1[1];
U32Tempt2[2] = U32Tempt1[2];
U32Tempt2[3] = U32Tempt1[3];
*pResult = *((uint32 * )U32Tempt2);
}
void INT32SCOPY(int32 * pVaule,int32 *pResult)
{
Octet *U32Tempt1;
Octet U32Tempt2[4];
U32Tempt1 = (Octet*)pVaule;
U32Tempt2[0] = U32Tempt1[0];
U32Tempt2[1] = U32Tempt1[1];
U32Tempt2[2] = U32Tempt1[2];
U32Tempt2[3] = U32Tempt1[3];
*pResult = *((int32 * )U32Tempt2);
}
void UpdateTime(PTime pToffset){
Time Tcur;
Getime(&Tcur);
Tcur.secs = Tcur.secs - pToffset->secs;
Tcur.nasecs = Tcur.nasecs - pToffset->nasecs + COST_TIME_FUNCTION;
if(Tcur.nasecs >= 1000000000){
Tcur.secs++;
Tcur.nasecs = Tcur.nasecs - 1000000000 ;
}
if(Tcur.nasecs <= -1000000000){
Tcur.secs--;
Tcur.nasecs = Tcur.nasecs + 1000000000 ;
}
Setime(&Tcur);
}
void SEND_FRMAETIME(uint8* Msg)
{
uint8 i = 0;
uint32 U32Tempt1;
uint32 U32Tempt2;
if(Msg[DesUDPOFFSETH] == PTPDesUdpPortH)
if((Msg[DesUDPOFFSETL] == EVENTPTPDesUdpPortL)||(Msg[DesUDPOFFSETL] == GERNERPTPDesUdpPortL))
{
switch(Msg[OffsetPTP_Control])
{
case PTP_SYNC_MESSAGE:
case PTP_DELAY_REQ_MESSAGE:
i = ToffetSync_Delay;
break;
//case PTP_FOLLOWUP_MESSAGE:
//i = ToffetFollow_Up;
//break;
case PTP_DELAY_RESP_MESSAGE:
i = ToffetDelay_Resp;
break;
default:
break;
}//end switch
if (i)
{
Getime((PTime)(&gTime_Para.CurTime));
U32Tempt1 = gTime_Para.CurTime.seconds;
U32Tempt2 = gTime_Para.CurTime.nanoseconds;
U32Tempt1 = U32Tempt1 >> 24 | (U32Tempt1&0x00FF0000) >> 8 | (U32Tempt1&0x0000FF00) <<8 |(U32Tempt1) <<24;
U32Tempt2 = U32Tempt2 >> 24 | (U32Tempt2&0x00FF0000) >> 8 | (U32Tempt2&0x0000FF00) <<8 |(U32Tempt2) <<24;
//gTime_Para.CurTime.seconds = U32Tempt >> 24 | (U32Tempt&0x00FF0000) >> 8 | (U32Tempt&0x0000FF00) <<8 |(U32Tempt) <<24;
//U32Tempt = gTime_Para.CurTime.nanoseconds;
//gTime_Para.CurTime.nanoseconds = U32Tempt >> 24 | (U32Tempt&0x00FF0000) >> 8 | (U32Tempt&0x0000FF00) <<8 |(U32Tempt) <<24;
//*(uint32 *)(Msg + i) = U32Tempt1;
memcpy(Msg + i, (uint8 *)&U32Tempt1,4);
//*(uint32 *)(Msg + i + 4) = U32Tempt2;
memcpy(Msg + i + 4, (uint8 *)&U32Tempt2,4);
//memcpy((Msg + i),(uint8*)&gTime_Para.CurTime,sizeof(TimeRepresentation));
}
}//end if
}//end function void SEND_FRMAETIME(uint8* Msg)
void PTP_init()
{
PTP_Sync_Or_Delay_Req* pReq_Message;
PTP_Sync_Or_Delay_Req* msg;
MasterInveral = 0;
gSysStatus &= ~SYS_BPTPSTABLE;
memset(gPTP_EVENT_MESSAGE , 0 , MAXOFPTP_EVENT_MESSAGE);
memset(&gTime_Para,0,sizeof(gTime_Para));
memcpy(gTime_Para.LocalUuid,gLOCALUUID,sizeof(gLOCALUUID));
memset(gTime_Para.Subdomain,0x52,16);
memset(gTime_Para.Parent_set.parent_subdomain,0x52,16);
pReq_Message = (PTP_Sync_Or_Delay_Req*)(gPTP_EVENT_MESSAGE);
PTP_Header_Construct(&(pReq_Message->Header),1,PTP_EVENT_PORT,PTP_DELAY_REQ_MESSAGE,gTime_Para.Subdomain);
PTP_HEADER_VERSER_ORDER(&pReq_Message->Header);
pReq_Message->Body.utcReasonable = TRUE;
pReq_Message->Body.parentPortField = PTP_EVENT_PORT;
pReq_Message->Header.flags[0] = 0x00;
pReq_Message->Header.flags[1] = 0x08;
memcpy(pReq_Message->Header.sourceUuid,gLOCALUUID,16);
memset(pReq_Message->Header.subdomain,0x52,16);
//pReq_Message->Header.flags[1] = 0x08;
//gTime_Para.Parent_set.parent_uuid[0] = 0xb0;
//gTime_Para.Parent_set.parent_uuid[1] = 0xa0;
gTime_Para.PTPIP[0] = 0xE0;
gTime_Para.PTPIP[1] = 0x00;
gTime_Para.PTPIP[2] = 0x01;
gTime_Para.PTPIP[3] = 0x81;
msg->Body.parentCommunicationTechnology = PTP_ETHER;
msg->Body.grandmasterCommunicationTechnology = PTP_ETHER;
gTime_Para.State = PTP_INITIALIZING;
#ifdef IEEE1588_CLOCK_MASTER
MasterInterval = 0;
#endif
}
// void PTP_Header_Construct(PPTP_Header pHeader,Octet * subdomain , uint8 MessageType)
// Descrption: constrcut a PTP_Message packet.
//
// parameter MessageType:
// If the message is of type Sync or Delay_Req, the value shall be 0x01.
// These messages shall be known as event messages.
// If the message is of type Delay_Resp, Follow_Up, or Management, the value shall be 0x02.
// the messages shall be known as general messages.
//
// parameter SourceUuid:suggest use LOCAL MAC Address.
void PTP_Header_Construct(PTP_Header* pHeader,uint8 MessageType,
uint16 SourcePortId,uint8 ControlNumber,uint8* subdomain)
{
pHeader->versionPTP = 1;
pHeader->versionNetwork = 1;
memcpy(pHeader->subdomain,subdomain,16);
pHeader->messageType = MessageType;
pHeader->sourceCommunicationTechnology = PTP_ETHER;
memcpy(pHeader->sourceUuid,gLOCALUUID,6);
pHeader->sourcePortId = SourcePortId;
pHeader->sequenceId = ++(gTime_Para.sequenceIdCreator);
pHeader->control = ControlNumber;
pHeader->flags[0] = 0x00;
pHeader->flags[1] = 0x08;
pHeader->reserved1 = 0x00;
memset(pHeader->reserved2,0x00,2) ;
}
//增加的函数,2005年6月20
//.......................
void CreateParentSet(PTP_Sync_Or_Delay_Req* pMessage)
{
memcpy(gTime_Para.Parent_set.parent_uuid,pMessage->Header.sourceUuid,6);
gTime_Para.Parent_set.parent_followup_capable = pMessage->Header.flags[1]&0x08;
gTime_Para.Parent_set.parent_last_sync_sequence_number = 0xFFFF;//pMessage->Header.sequenceId;
memcpy(&gTime_Para.Parent_set.parent_subdomain,&pMessage->Header.subdomain,16);
gTime_Para.Parent_set.parent_port_id = pMessage->Header.sourcePortId;
return;
}//end function void CreateParentSet(PTP_Sync_Or_Delay_Req*)
void UpdateParentSet(PTP_Sync_Or_Delay_Req* pMessage)
{
//gTime_Para.Parent_set.parent_port_id = pMessage->Header.sourcePortId;
gTime_Para.Parent_set.parent_last_sync_sequence_number = pMessage->Header.sequenceId;
//memcpy(&gTime_Para.Parent_set.Tsync_recv, pMessage + NET_BUFF_SIZE,sizeof(TimeRepresentation));
//memcpy(&gTime_Para.Parent_set.Tsync_recv, &gTime_Para.CurTime,sizeof(TimeRepresentation));
//memcpy(&gTime_Para.Parent_set.Tsync_origin,&pMessage->Body.originTimestamp,sizeof(TimeRepresentation));
#if 0
memcpy(&gTime_Para.Tsync_recv, &gTime_Para.CurTime,sizeof(TimeRepresentation));
memcpy(&gTime_Para.Tsync_origin,&pMessage->Body.originTimestamp,sizeof(TimeRepresentation));
#endif
gTime_Para.Tsync_recv.seconds = gTime_Para.CurTime.seconds;
gTime_Para.Tsync_recv.nanoseconds = gTime_Para.CurTime.nanoseconds;
INT32UCOPY(&pMessage->Body.originTimestamp.seconds , &gTime_Para.Tsync_origin.seconds);
INT32SCOPY(&pMessage->Body.originTimestamp.nanoseconds ,&gTime_Para.Tsync_origin.nanoseconds);
return;
}//end function void UpdateParentSet(PTP_Sync_Or_Delay_Req*)
void PTP_RECV_PROCESS(uint8* inbuf)
{
PTP_Header* pHeader;
uint8* pU8;
pU8 = inbuf;
pHeader = ( PTP_Header*)(pU8);
switch(pHeader->control)
{
case PTP_SYNC_MESSAGE :
SYNC__OR_DELAY_REQ_MSG_VERSER_ORDER((PPTP_Sync_Or_Delay_Req)pU8);
PTP_RECV_SYNC(pU8);
break;
case PTP_DELAY_REQ_MESSAGE:
SYNC__OR_DELAY_REQ_MSG_VERSER_ORDER((PPTP_Sync_Or_Delay_Req)pU8);
PTP_RECV_DELAY_REQ(pU8);
break;
case PTP_FOLLOWUP_MESSAGE:
FOLLOWUP_MSG_VERSER_ORDER((PPTP_Follow_Up) pU8);
PTP_RECV_FOLLOWUP(pU8);
break;
case PTP_DELAY_RESP_MESSAGE:
DELAY_RESP_VERSER_ORDER((PPTP_Delay_Resp) pU8);
PTP_RECV_DELAY_RESP(pU8);
break;
case PTP_MANAGEMENT_MESSAGE:
//PTP_RECV_MANAGEMENT(pU8);
break;
default:
break;
}//end switch(pHeader->messageType)
}//end function void PTP_RECV_PROCESS(uint8* pUdpData)
void PTP_RECV_SYNC(uint8* pPTPData)
{
PTP_Sync_Or_Delay_Req* pMessage;
pMessage = (PTP_Sync_Or_Delay_Req* )pPTPData;
//if(gTime_Para.State == PTP_SLAVE)
//{
if(!(memcmp(pMessage->Header.subdomain,gTime_Para.Subdomain,16)))
{
//if( pMessage->Header.sequenceId > gTime_Para.Parent_set.parent_last_sync_sequence_number)
//{
UpdateParentSet(pMessage);
if((pMessage->Header.flags[1])&0x08 == 0) //同步报文后是否还有Fllowup报文
{
//memcpy(&gTime_Para.Tsync_recv, &gTime_Para.CurTime,sizeof(TimeRepresentation));
//memcpy(&gTime_Para.Tsync_origin,&pMessage->Body.originTimestamp,sizeof(TimeRepresentation));
PTP_Send_Delay_Req();
}
//}
}
//}else{
// //UpDateTime(&pMessage->Body.originTimestamp);
// CreateParentSet(pMessage);
// gTime_Para.State = PTP_SLAVE;
//}
}// end funcion void PTP_RECV_SYNC(uint8* pPTPData)
void PTP_RECV_FOLLOWUP(uint8* pPTPData)
{
PTP_Follow_Up* pMessage;
//TimeDiff Timeoffset;
pMessage = (PTP_Follow_Up*)pPTPData;
#if 0
if(gTime_Para.State != PTP_SLAVE)
{
//UpDateTime(&pMessage->Body.preciseOriginTimestamp);
//CreateParentSet(pMessage);
//gTime_Para.State = PTP_SLAVE;
return;
}
#endif
if(memcmp(pMessage->Header.subdomain,gTime_Para.Subdomain,16)==0)
//if(memcmp(pMessage->Header.sourceUuid,gTime_Para.Parent_set.parent_uuid,6) == 0)
{
if( pMessage->Body.associatedSequenceId == gTime_Para.Parent_set.parent_last_sync_sequence_number)
{
INT32UCOPY(&pMessage->Body.preciseOriginTimestamp.seconds,&gTime_Para.Tsync_origin.seconds);
INT32SCOPY(&pMessage->Body.preciseOriginTimestamp.nanoseconds,&gTime_Para.Tsync_origin.nanoseconds);
PTP_Send_Delay_Req();
}
}
}//end funxion void PTP_RECV_FOLLOWUP(uint8* pPTPData)
void PTP_RECV_MANAGEMENT(uint8* pPTPData)
{
//有待完善
//return
}//end funcion void PTP_RECV_MANAGEMENT(uint8* pPTPData)
void PTP_RECV_DELAY_REQ(uint8* pPTPData)
{
PTP_Sync_Or_Delay_Req* pMessage;
pMessage = (PTP_Sync_Or_Delay_Req*)pPTPData;
PTP_Send_PTP_REQ_RESP(pMessage->Header.sourceUuid , pMessage->Header.sequenceId);
return;
}//end funcion voidPTP_RECV_DELAY_REQ(uint8* pPTPData)
void PTP_Send_PTP_SYNC_MESSAGE()
{
PTP_Sync_Or_Delay_Req* msg;
POutSock posock;
posock = GetOutSock(PROTOCOL_UDP_OR_ICMP);
posock->dstip = PTPIPADDR;
posock->dstport = PTP_GERNERAL_PORT;
posock->srcport = PTP_GERNERAL_PORT;
posock->length = sizeof(PTP_Sync_Or_Delay_Req);
memcpy(posock->payload,gPTP_EVENT_MESSAGE + 42,posock->length);
msg = (PTP_Sync_Or_Delay_Req*)posock->payload;
msg->Header.sequenceId = ++ gTime_Para.sequenceIdCreator;
gTime_Para.BackupsequenceId = msg->Header.sequenceId;
msg->Header.control = PTP_SYNC_MESSAGE;
msg->Header.messageType = 0x01;
//msg->Header.flags[0]=0x00;
//msg->Header.flags[1]=0x08;
SYNC__OR_DELAY_REQ_MSG_VERSER_ORDER(msg);
IPOutput(posock, UDP_PROTOCOL);
//udp_send((unsigned char * )msg, gTime_Para.PTPIP, PTP_EVENT_PORT, sizeof(PTP_Sync_Or_Delay_Req));
memcpy(&gTime_Para.BackTorigin,&gTime_Para.CurTime,sizeof(TimeRepresentation));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -