📄 enet_ptpd.c
字号:
//
// Initialize a sample web server application.
//
httpd_init();
//
// Main Application Loop (for systems with no RTOS). Run every SYSTICK.
//
while(true)
{
//
// Wait for an event to occur.
//
while(!(g_ulFlags & MODE_FLAG_MASK))
{
}
//
// Check if a SYSTICK has occurred.
//
if(HWREGBITW(&g_ulFlags, FLAG_SYSTICK))
{
//
// Clear the SysTick interrupt flag.
//
HWREGBITW(&g_ulFlags, FLAG_SYSTICK) = 0;
//
// Run the Luminary lwIP system tick.
//
lwip_tick(SYSTICKMS);
//
// Clear PPS output when needed and display time of day.
//
if(HWREGBITW(&g_ulFlags, FLAG_PPSOFF))
{
//
// Negate the PPS output.
//
GPIOPinWrite(PPS_GPIO_BASE, PPS_GPIO_PIN, 0);
//
// Indicate that we have negated the PPS output.
//
HWREGBITW(&g_ulFlags, FLAG_PPSOFF) = 0;
//
// Display Date and Time.
//
DisplayDate(g_ulSystemTimeSeconds, 48);
DisplayTime(g_ulSystemTimeSeconds, 56);
}
//
// Setup to disable the PPS output on the next pass.
//
if(HWREGBITW(&g_ulFlags, FLAG_PPSOUT))
{
//
// Setup to turn off the PPS output.
//
HWREGBITW(&g_ulFlags, FLAG_PPSOUT) = 0;
HWREGBITW(&g_ulFlags, FLAG_PPSOFF) = 1;
}
}
//
// Check if an RX Packet was received.
//
if(HWREGBITW(&g_ulFlags, FLAG_RXPKT))
{
//
// Clear the Rx Packet interrupt flag.
//
HWREGBITW(&g_ulFlags, FLAG_RXPKT) = 0;
//
// Run the Luminary lwIP system tick, but with no time, to indicate
// an RX or TX packet has occurred.
//
lwip_tick(0);
}
//
// Check if a TX Packet was sent.
//
if(HWREGBITW(&g_ulFlags, FLAG_TXPKT))
{
//
// Clear the Tx Packet interrupt flag.
//
HWREGBITW(&g_ulFlags, FLAG_TXPKT) = 0;
//
// Run the Luminary lwIP system tick, but with no time, to indicate
// an RX or TX packet has occurred.
//
lwip_tick(0);
//
// Enable Ethernet TX Packet Interrupts.
//
EthernetIntEnable(ETH_BASE, ETH_INT_TX);
}
//
// If IP address has been assigned, initialize the PTPD software (if
// not already initialized).
//
if(HWREGBITW(&g_ulFlags, FLAG_IPADDR) &&
!HWREGBITW(&g_ulFlags, FLAG_PTPDINIT))
{
ptpd_init();
HWREGBITW(&g_ulFlags, FLAG_PTPDINIT) = 1;
}
//
// If PTPD software has been initialized, run the ptpd tick.
//
if(HWREGBITW(&g_ulFlags, FLAG_PTPDINIT))
{
ptpd_tick();
}
}
}
//*****************************************************************************
//
// The following set of functions are LMI Board/Chip Specific implementations
// of functions required by PTPd software. Prototypes are defined in ptpd.h,
// or one of its included files.
//
//*****************************************************************************
//*****************************************************************************
//
// Display Statistics. For now, do nothing, but this could be used to either
// update a web page, send data to the serial port, or to the OLED display.
//
// Refer to the ptpd software "src/dep/sys.c" for example code.
//
//*****************************************************************************
void
displayStats(RunTimeOpts *rtOpts, PtpClock *ptpClock)
{
}
//*****************************************************************************
//
// This function returns the local time (in PTPd internal time format). This
// time is maintained by the SysTick interrupt.
//
// Note: It is very important to ensure that we detect cases where the system
// tick rolls over during this function. If we don't do this, there is a race
// condition that will cause the reported time to be off by a second or so
// once in a blue moon. This, in turn, causes large perturbations in the
// 1588 time controller resulting in large deltas for many seconds as the
// controller tries to compensate.
//
//*****************************************************************************
void
getTime(TimeInternal *time)
{
unsigned long ulTime1;
unsigned long ulTime2;
unsigned long ulSeconds;
unsigned long ulPeriod;
unsigned long ulNanoseconds;
//
// We read the SysTick value twice, sandwiching taking snapshots of
// the seconds, nanoseconds and period values. If the second SysTick read
// gives us a higher number than the first read, we know that it wrapped
// somewhere between the two reads so our seconds and nanoseconds
// snapshots are suspect. If this occurs, we go round again. Note that
// it is not sufficient merely to read the values with interrupts disabled
// since the SysTick counter keeps counting regardless of whether or not
// the wrap interrupt has been serviced.
//
do
{
ulTime1 = SysTickValueGet();
ulSeconds = g_ulSystemTimeSeconds;
ulNanoseconds = g_ulSystemTimeNanoSeconds;
ulPeriod = SysTickPeriodGet();
ulTime2 = SysTickValueGet();
#ifdef DEBUG
//
// In debug builds, keep track of the number of times this function was
// called just as the SysTick wrapped.
//
if(ulTime2 > ulTime1)
{
g_ulSysTickWrapDetect++;
g_ulSysTickWrapTime = ulSeconds;
}
#endif
}
while(ulTime2 > ulTime1);
//
// Fill in the seconds field from the snapshot we just took.
//
time->seconds = ulSeconds;
//
// Fill in the nanoseconds field from the snapshots.
//
time->nanoseconds = (ulNanoseconds + (ulPeriod - ulTime2) * TICKNS);
//
// Adjust for any case where we accumulate more than 1 second's worth of
// nanoseconds.
//
if(time->nanoseconds >= 1000000000)
{
#ifdef DEBUG
g_ulGetTimeWrapCount++;
#endif
time->seconds++;
time->nanoseconds -= 1000000000;
}
}
//*****************************************************************************
//
// This function will set the local time (provided in PTPd internal time
// format). This time is maintained by the SysTick interrupt.
//
//*****************************************************************************
void
setTime(TimeInternal *time)
{
sys_prot_t sProt;
//
// Update the System Tick Handler time values from the given PTPd time
// (fine-tuning is handled in the System Tick handler). We need to update
// these variables with interrupts disabled since the update must be
// atomic.
//
#ifdef DEBUG
UARTprintf("Setting time %d.%09d\n", time->seconds, time->nanoseconds);
#endif
sProt = sys_arch_protect();
g_ulSystemTimeSeconds = time->seconds;
g_ulSystemTimeNanoSeconds = time->nanoseconds;
sys_arch_unprotect(sProt);
}
//*****************************************************************************
//
// Get the RX Timestamp. This is called from the lwIP low_level_input function
// when configured to include PTPd support.
//
//*****************************************************************************
void
getRxTime(TimeInternal *psRxTime)
{
unsigned long ulNow;
unsigned long ulTimestamp;
//
// Get the current IEEE1588 time.
//
getTime(psRxTime);
//
// If we are using the hardware timestamp mechanism, get the timestamp and
// use it to adjust the packet timestamp accordingly.
//
if(HWREGBITW(&g_ulFlags, FLAG_HWTIMESTAMP))
{
//
// Read the (now frozen) timer value and the still-running timer.
//
ulTimestamp = TimerValueGet(TIMER3_BASE, TIMER_B);
ulNow = TimerValueGet(TIMER3_BASE, TIMER_A);
//
// Adjust the current time with the difference between now and the
// actual timestamp.
//
adjust_rx_timestamp(psRxTime, ulTimestamp, ulNow);
}
return;
}
//*****************************************************************************
//
// This function returns a random number, using the functions in random.c.
//
//*****************************************************************************
UInteger16
getRand(UInteger32 *seed)
{
unsigned long ulTemp;
UInteger16 uiTemp;
//
// Re-seed the random number generator.
//
RandomAddEntropy(*seed);
RandomSeed();
//
// Get a random number and return a 16-bit, truncated version.
//
ulTemp = RandomNumber();
uiTemp = (UInteger16)(ulTemp & 0xFFFF);
return(uiTemp);
}
//*****************************************************************************
//
// Based on the value (adj) provided by the PTPd Clock Servo routine, this
// function will adjust the SysTick periodic interval to allow fine-tuning of
// the PTP Clock.
//
//*****************************************************************************
Boolean
adjFreq(Integer32 adj)
{
unsigned long ulTemp;
//
// Check for max/min value of adjustment.
//
if(adj > ADJ_MAX)
{
adj = ADJ_MAX;
}
else if(adj < -ADJ_MAX)
{
adj = -ADJ_MAX;
}
//
// Convert input to nanoseconds / systick.
//
adj = adj / SYSTICKHZ;
//
// Get the nominal tick reload value and convert to nano seconds.
//
ulTemp = (SysCtlClockGet() / SYSTICKHZ) * TICKNS;
//
// Factor in the adjustment.
//
ulTemp -= adj;
//
// Get a modulo count of nanoseconds for fine tuning.
//
g_ulSystemTickHigh = ulTemp % TICKNS;
//
// Set the reload value.
//
g_ulNewSystemTickReload = ulTemp / TICKNS;
//
// Return.
//
return(TRUE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -