Introduction
DLR (Device Level Ring) is a Layer 2 redundancy protocol operating independently of CIP (Common Industrial Protocol). It provides fault-tolerant network communication by enabling devices to detect and recover from network failures in ring topologies. DLR relies on circulation of periodic frames called Beacons or Announce frames to monitor network health, while using various other frame types to identify fault locations and manage network participation.
A DLR network consists of the following components:
- DLR Supervisor: Responsible for network integrity monitoring by transmitting periodic Beacon or Announce frames at configurable intervals. The Supervisor (typically a controller or PLC) detects topology transitions between ring and linear configurations, managing port states accordingly. When operating in a healthy ring, the Supervisor blocks one port to prevent network loops, but opens this port when a fault is detected to maintain connectivity.
- DLR Node: Forwards Beacon/Announce frames between ports without modification while monitoring for continuous frame reception. If frames are missed, the Node reports status to the Supervisor. The protocol identifier 0x80E1 (positioned immediately after the destination MAC) identifies DLR frames to the firmware, triggering specialized processing paths.
All devices in a DLR network, regardless of role, participate in fault detection and network status reporting, enabling rapid recovery from link or device failures.
Frame Types
DLR uses several specialized frame types to maintain network integrity and detect faults. Each frame type serves a specific purpose in the DLR protocol and is handled differently depending on whether the device is operating as a Node or Supervisor.
1. Beacon
The primary mechanism for monitoring ring health, Beacon frames are transmitted periodically by the Supervisor on both ports simultaneously according to the configured beaconInterval. These frames traverse the entire network in opposite directions, eventually reaching the Supervisor's opposite ports when the ring is intact.
- Interval: Configurable, with minimum value of 100 microseconds and default value of 400 microseconds
- Timeout: Failure to receive a Beacon within the configured
beaconTimeout triggers a Fault state
- Processing: Cut-through forwarding by Nodes
- Generation: Supervisor only
- Handling differences:
- Supervisor: Generates Beacons, monitors reception on opposite ports
- Node: Forwards Beacons, monitors reception frequency
2. Locate Fault
Generated by the Supervisor when a Beacon timeout or other fault event occurs, prompting all devices to report their neighbor status.
- Processing: Cut-through forwarding by Nodes
- Generation: Supervisor only
- Response: Triggers Neighbor Check Request generation
- Handling differences:
- Supervisor: Generates frame, collects responses to identify fault location
- Node: Forwards frame, initiates neighbor status verification
3. Neighbor Check Request
Generated by all devices (Nodes and Supervisor) in response to fault events to verify connectivity with adjacent devices.
- Generation: All devices on each port
- Frequency: 3 attempts at 100ms intervals
- Processing: Forwarded to Host for response
- Handling differences:
- Supervisor: Both generates and processes these frames
- Node: Both generates and processes these frames
4. Neighbor Check Response
Reply to a Neighbor Check Request confirming link integrity between adjacent devices.
- Processing: Consumed by receiving device, not forwarded
- Timeout: If no response after 3 requests, indicates port/device fault
- Handling differences:
- Supervisor: Processes responses to build network fault map
- Node: Uses responses to determine local connectivity status
5. Link Status/Neighbor Status
Notification sent to the Supervisor when a device detects a link failure or neighbor connectivity issue.
- Processing: Cut-through forwarding by Nodes. Consumed by the Supervisor.
- Purpose: Informs Supervisor about specific fault locations
- Handling differences:
- Supervisor: Processes these frames to identify fault locations
- Node: Generates these frames when local faults are detected
6. Sign On
Contains network participation information, allowing the Supervisor to build a complete map of the ring.
- Processing: Each Node adds its information before forwarding
- Path: Sent by Supervisor on one port, traverses network with each Node adding data
- Queue: Sent to Host via high-priority Host queues
- Handling differences:
- Supervisor: Initiates and ultimately processes complete Sign On data
- Node: Adds local information and forwards
7. Announce
Legacy alternative to Beacons, operating at slower intervals for backward compatibility.
- Processing: Cut-through forwarding
- Handling differences:
- Supervisor: Generates Announce frames every 1 second for legacy networks
- Node: Forwards frames but doesn't process them
Timers
DLR operation relies heavily on precise timing mechanisms to monitor network health and detect faults. Multiple timers track beacon reception, neighbor check responses, and other time-sensitive operations. This timing infrastructure is critical for both Node and Supervisor implementations, though with different requirements for each role.
Hardware Timers
ICSS IEP Watchdog Timers for Beacon Timeout
Our implementation uses ICSS IEP Watchdog Timers for tracking beacon timeout:
- Timer Hardware: IEP_PD_WD and IEP_PDI_WD watchdog timers
- Clock Configuration: 10μs granularity via PRU-ICSS register PRUSS_IEP_WD_PREDIV
- Timing Precision: Values must be multiples of 10μs (e.g., 400μs or 410μs, but not 405μs)
- Operation: When a beacon is received, the corresponding timer is restarted, preventing ISR triggering
- Timeout Handling: Timer expiry triggers the appropriate ISR to handle potential fault conditions
ICSS IEP Compare Events for Beacon Transmission in Supervisor mode
The Supervisor implementation requires precise timing for beacon transmission and announce suppression:
- Compare Events 13 and 14: Used for beacon transmission timing on both ports
- Compare Event 15: Used for announce suppression timeout management
- Operation: These compare events trigger at precise intervals to ensure accurate frame transmission timing
- Configuration: Set during Supervisor initialization to match the configured beacon interval in EIP_DLR_startBeaconIntervalTimer - then reprogrammed by the firmware as needed.
Software Timers
For less time-critical functions, software timers are employed:
- Usage: Neighbor Check Response timeouts (100ms intervals)
- Implementation: Standard software timer mechanism (FreeRTOS ClockP)
- Rationale: Less stringent timing requirements compared to beacon monitoring
Timer Configuration
- Initial Setup: Default timer values configured in EIP_DLR_init API function
- Dynamic Reconfiguration: Beacon timeout timers are updated with network parameters when the first beacon is received from the Supervisor
- Role-specific Configuration:
- Supervisor:
- Configures IEP Compare Events 13 and 14 for beacon transmission
- Configures IEP Compare Event 15 for announce suppression
- Configures Watchdog timers for beacon timeout monitoring
- Node: Configures Watchdog timers primarily for beacon reception monitoring
Timer-related Events
- Beacon Reception: Resets the corresponding port's beacon timeout timer
- Beacon Timeout: Triggers fault detection procedures
- Beacon Transmission: Triggered by IEP Compare Events 13 and 14 in Supervisor mode
- Announce Suppression: Managed by IEP Compare Event 15 in Supervisor mode
- Neighbor Check Timeout: Initiates neighbor status reporting after three failed attempts
Interrupts
The DLR implementation relies on various interrupts to handle time-sensitive events, network state changes, and frame processing. These interrupts are critical for maintaining network integrity and ensuring rapid response to fault conditions.
1. Timer Expiry Interrupts
When configured timers expire, they trigger corresponding ISRs to handle timeout conditions:
Beacon Timeout Interrupts (Node and Supervisor)
Neighbor Check Timeout Interrupts (Node and Supervisor)
2. Link Break Interrupts
DLR events triggered by physical link state changes require immediate processing:
3. State Change Processing Interrupts
Fast ISR scheme for host communication where firmware processes DLR frames:
- EIP_DLR_port0ISR : Fast ISR to process Port 0 DLR events
- EIP_DLR_port1ISR : Fast ISR to process Port 1 DLR events
- Operation: Parses fields, copies data to ICSS Shared Memory locations, triggers ARM interrupt
- Role Differences:
- Node: Primarily monitors state changes from Supervisor
- Supervisor: Also processes network topology changes and fault reports
4. Host Queue Processing Interrupts
For DLR frames requiring host processing via high-priority queues:
- EIP_DLR_processDLRFrame : DLR frame processing callback programmed as RT-callback in ICSS_EMAC
- Frame Types: Primarily Sign-On, Neighbor Check Request and Link Status/Neighbor Status frames
- Priority: Highest priority queue to ensure timely processing
- Role Differences:
- Node: Processes requests and generates appropriate responses
- Supervisor: Manages ring participant information and fault location tracking
DLR State Machine and Actions
Overview
The DLR protocol relies on a state machine to track network status and coordinate responses to network events. The implementation maintains state information in ICSS Shared RAM and responds to various events that may occur on either or both ports. With the addition of Supervisor functionality, the state machine now handles both Node and Supervisor roles with their respective responsibilities.
State Machine Implementation
Storage Location
- State information is stored in ICSS Shared RAM at the location pointed to by DLR_STATE_MACHINE_OFFSET
- Port-specific events are stored in ICSS DMEM_0 and DMEM_1 for Port 0 and Port 1 respectively at DLR_PORT_EVENTS_OFFSET
- Common events affecting both ports are stored at DLR_COMMON_EVENTS_OFFSET
Node States
1. No DLR (Idle) - DLR_IDLE_STATE_VAL
- Description: Initial state after boot-up, before any DLR frames are received
- Configuration: Beacon timeout timers set with default values
- Flags: All flags in reset state
- Role Differences:
- Node: Waits for beacon frames
- Supervisor: Transitions to Fault state when activated to begin beacon transmission
2. Fault - DLR_FAULT_STATE_VAL
- Description: Indicates a detected issue in the ring topology
- Triggers:
- Initial state when first beacon is received
- Link breaks
- Network reset
- Beacon timeout
- Configuration: When first beacon is received in reset state, the beacon timeout interval is copied from the frame and timeout timer is configured in Fast ISR
- Role Differences:
- Node: Monitors for state change from Supervisor
- Supervisor: Actively manages fault detection and recovery, blocks one port in linear topology
3. Normal - DLR_NORMAL_STATE_VAL
- Description: Indicates ring is up and functional
- Triggers: Supervisor transitions from Fault to Normal when it receives beacon frames on both ports
- Role Differences:
- Node: Continues normal frame forwarding
- Supervisor: Blocks one port to prevent loops, continues beacon transmission
State Machine Diagram
DLR Node
EtherNet/IP DLR Node State Machine Diagram
- For State-Event-Action Table for Beacon Frame Based Non-Supervisor Ring Node, refer to the Table 9-5.22 of EtherNet/IP Specification: Vol2_1.33
DLR Supervisor
EtherNet/IP DLR Supervisor State Machine Diagram
- For State-Event-Action Table for Ring Supervisor Node, refer to the Table 9-5.26 of EtherNet/IP Specification: Vol2_1.33
Common Events
Events common to both ports stored at DLR_COMMON_EVENTS_OFFSET:
- DLR_RING_NORMAL_TRANSITION: Node transitioned from Fault to Normal; perform appropriate actions
- DLR_RING_FAULT_TRANSITION: Node transitioned from Idle to Fault; configure timers and perform actions
- DLR_STOP_BOTH_TIMERS: Stop both beacon timeout timers
- DLR_PORT0_BEACON_RCVD: Beacon received on Port 0
- DLR_PORT1_BEACON_RCVD: Beacon received on Port 1
- DLR_RESET_EVENT_OCCURED: Reset the DLR state machine
Port Events
Events specific to individual ports stored in ICSS DMEM_0 and DMEM_1 at DLR_PORT_EVENTS_OFFSET:
Frame Reception Events
- DLR_LOCFAULT_RCVD: Locate Fault packet received
- DLR_NCREQ_RCVD: Neighbor Check request packet received
- DLR_NCRES_RCVD: Neighbor Check response packet received
- DLR_RING_FAULT_RCVD: Beacon with fault status received
- DLR_FLUSH_TABLE_RCVD: Flush table packet received
Timer Control Events
- DLR_START_TIMER: Start beacon timeout timer for the port
- DLR_TIMER_RUNNING: Beacon timeout timer running and not expired
Configuration and Action Events
- DLR_UPDATE_SUP_CFG: Supervisor changed, update parameters
- DLR_SEND_LEARNING_UPDATE: Send learning update frame
- IS_A_DLR_FRAME: Internal flag for firmware implementation
- COMPARE_SUP_PRED: Internal flag for comparing supervisor precedence
- UPDATE_NEW_SUP_CFG: Internal flag for updating supervisor configuration
- DLR_DROP_PACKET: Internal flag for packet dropping
- DLR_HOST_FWD: Internal flag for host forwarding
Quality of Service (QoS)
All the DLR frames are sent to the host in the highest priority queue. EIP_DLR_processDLRFrame is the callback API that handles the different DLR frames received by the application in the highest priority queue.
EtherNet/IP Stack - ICSS DLR Driver Interface
All DLR information relevant to the EIP stack is stored in the structure dlrStruct which maps directly to the DLR Object (0x47) as defined in the standard. The attribute IDs refer to the corresponding IDs for the DLR Object.
The structure is used as a global in icss_dlr.c. A third party stack can declare this as an extern to access the member variables.
/**
* \brief DLR parent structure through which all other structures can be accessed
*/
typedef struct
{
/**Supervisor config. Attribute ID 4*/
superConfig supConfig;
/**Supervisor address. Attribute ID 10*/
activeSuperAddr addr;
/**State Machine variables. Attributes 1 through 3*/
dlrStateMachineVar SMVariables;
/**DLR Capabilities, flag
The Map is as follows
* 0 : Announce Based Ring Node
* 1 : Beacon based Ring Node
* 2-4 : Reserved
* 5 : Supervisor capable
* 6 : Redundant capable
* 7 : Flush Table frame capable
* 8-31 : Reserved
*/
/**DLR Capabilities of the device. Attribute ID 12*/
uint32_t dlrCapabilities;
/**Active Supervisor precedence. Attribute ID 11*/
uint8_t activeSuperPred;
HwiP_Object port0IntObject;
HwiP_Object port1IntObject;
HwiP_Object beaconTimeoutIntP0Object;
HwiP_Object beaconTimeoutIntP1Object;
HwiP_Object announceSuppressionTimeoutIntObject;
/**DLR Port 0 Interrupt number for ARM*/
uint32_t port0IntNum;
/**DLR Port 1 Interrupt number for ARM*/
uint32_t port1IntNum;
/**DLR interrupt for beacon timeout for Port 0*/
uint32_t beaconTimeoutIntNum_P0;
/**DLR interrupt for beacon timeout for Port 1*/
uint32_t beaconTimeoutIntNum_P1;
/**Flag to indicate if switch over period is active*/
uint8_t isSwitchOverPeriodActive;
/**Flag to indicate that the active ring supervisor parameters have changed
and its waiting for the 2x beacon timeout before restarting beacon transmission */
uint8_t configChangeSuppressionActive;
/**Attribute ID's 6 and 7*/
lastActiveNode activeNode[2];
/**Number of Ring Faults since power up. Attribute ID 5*/
uint16_t numRingFaultsSincePowerUp;
/**Number of ring participants. Attribute ID 8*/
uint16_t ringParticipantsCount;
/**pointer to array of structures. Attribute ID 9*/
protocolParticipants ringNodes[DLR_MAX_NODES_SUPPORTED];
/** variable to track if supervisor is supported - need to be set from the application */
uint8_t isSupervisorSupported;
} dlrStruct;
DLR Object (Class Code: 0x47) Attributes
Attribute 1: Network Topology
- Access: Get
- Description: Indicates the network topology type
- Values:
- Driver Interface:
dlrHandle->dlrObj->SMVariables.topology
Attribute 2: Network Status
- Access: Get
- Description: Indicates current ring status
- Values:
- 0: Normal
- 1: Ring Fault
- 2: Unexpected Loop Detection
- 3: Partial Fault
- 4: Rapid Fault/Restore Cycle
- Driver Interface:
dlrHandle->dlrObj->SMVariables.status
Attribute 3: Ring Supervisor Status
- Access: Get
- Description: Indicates supervisor capability status
- Values:
- 0: Backup Ring Supervisor
- 1: Active Ring Supervisor
- 2: Ring Node
- 3: Non-DLR Node
- Driver Interface:
dlrHandle->dlrObj->SMVariables.superStatus
Attribute 4: Ring Supervisor Config
- Access: Get/Set
- Members:
- SuperEnable (BOOL)
- BeaconInterval (UINT)
- BeaconTimeout (UINT)
- VLANID (UINT)
- SuperPrecedence (USINT)
- Driver Interface:
Attribute 5: Ring Fault Count
- Access: Get/Set
- Description: Number of ring faults since power-up
- Driver Interface:
Attribute 6: Last Active Node on Port 1
- Access: Get
- Members:
- IP Address (UDINT)
- MAC Address (ARRAY of 6 USINTs)
- Driver Interface:
dlrHandle->dlrObj->activeNode[0]
Attribute 7: Last Active Node on Port 2
- Access: Get
- Members:
- IP Address (UDINT)
- MAC Address (ARRAY of 6 USINTs)
- Driver Interface:
dlrHandle->dlrObj->activeNode[1]
Attribute 8: Ring Participants Count
- Access: Get
- Description: Number of nodes in ring
- Driver Interface:
dlrHandle->dlrObj->ringParticipantsCount
Attribute 9: Ring Protocol Participants List
- Access: Get
- Members per entry:
- IP Address (UDINT)
- MAC Address (ARRAY of 6 USINTs)
- Driver Interface:
dlrHandle->dlrObj->ringNodes[]
Attribute 10: Active Supervisor Address
- Access: Get
- Members:
- IP Address (UDINT)
- MAC Address (ARRAY of 6 USINTs)
- Driver Interface:
dlrHandle->dlrObj->addr
Attribute 11: Active Supervisor Precedence
- Access: Get
- Description: Precedence value of active supervisor
- Driver Interface:
dlrHandle->dlrObj->activeSuperPred
Attribute 12: Capability Flags
- Access: Get
- Description: Bitmap indicating supported capabilities
- Bits:
- Bit 0: Announce-based Ring Supervisor
- Bit 1: Beacon-based Ring Supervisor
- Bits 2-31: Reserved
- Driver Interface:
dlrHandle->dlrObj->capabilityFlags
DLR Services
Service 0x4E: Clear_Rapid_Faults
Service 0x4F: Restart_Sign_On
Service 0x53: Verify_Fault_Location
Important Notes
- To enable the DLR Supervisor capability, the
dlrHandle->dlrObj->isSupervisorSupported needs to be set to true (1).
- To track attribute 9, the driver uses a static array of fixed length. To increase/decrease the size of this array - update the DLR_MAX_NODES_SUPPORTED macro in the
icss_dlr.h file.
Initialization
Basic Initialization
DLR functionality is initialized and controlled through the following APIs:
- EIP_DLR_init : Initializes the DLR subsystem with default parameters
- Sets up data structures and state machine
- Configures default timer values
- Allocates resources for DLR operation
- Must be called once at system startup before any other DLR functions
- EIP_DLR_start : Activates DLR functionality in the firmware
- Enables DLR frame processing
- Starts beacon monitoring (Node mode) or transmission (Supervisor mode)
- Can be called at runtime to enable DLR after initialization
- EIP_DLR_stop : Deactivates DLR functionality in the firmware
- Disables DLR frame processing
- Stops all DLR-related timers
- Can be called at runtime to disable DLR temporarily
- EIP_DLR_addModuleIPAddress : Configures the IP address for the DLR node
- Must be called after IP address acquisition
- Critical to ensure that the DLR frames have a valid IP address
- If this is not called, DLR frames will not have the IP address and will contain only MAC address
- Can be updated if IP address changes during operation
Link Change Callback
To handle specific link change related processing, the following DLR API functions must be assigned to the ICSS EMAC Link Change Callback hooks.
/* Register Callback APIs for Link Break*/
((((ICSS_EMAC_Object *)emachandle->object)->callBackObject).port0LinkCallBack).callBack = (ICSS_EMAC_CallBack)EIP_DLR_port0ProcessLinkBrk;
((((ICSS_EMAC_Object *)emachandle->object)->callBackObject).port0LinkCallBack).userArg = (void*)icssEipHandle;
((((ICSS_EMAC_Object *)emachandle->object)->callBackObject).port1LinkCallBack).callBack = (ICSS_EMAC_CallBack)EIP_DLR_port1ProcessLinkBrk;
((((ICSS_EMAC_Object *)emachandle->object)->callBackObject).port1LinkCallBack).userArg = (void*)icssEipHandle;
When working with a use case that enables both DLR and Precision Time Protocol (PTP) where both protocols have link change related processing, the following code can be taken as a reference.
void EIP_DLR_TIMESYNC_port0ProcessLinkBrk(void* icssEmacVoidPtr, uint8_t linkStatus, void *eipVoidPtr)
{
EIP_Handle eipHandle = (EIP_Handle)eipVoidPtr;
/* Process DLR Link Break */
EIP_DLR_port0ProcessLinkBrk(linkStatus, (void *)(eipHandle->dlrHandle));
/* Process TimeSync Link Break */
TimeSync_Port1linkResetCallBack(linkStatus, (void *)(eipHandle->timeSyncHandle));
}
void EIP_DLR_TIMESYNC_port1ProcessLinkBrk(void* icssEmacVoidPtr, uint8_t linkStatus, void *eipVoidPtr)
{
EIP_Handle eipHandle = (EIP_Handle)eipVoidPtr;
/* Process DLR Link Break */
EIP_DLR_port1ProcessLinkBrk(linkStatus, (void *)(eipHandle->dlrHandle));
/* Process TimeSync Link Break */
TimeSync_Port2linkResetCallBack(linkStatus, (void *)(eipHandle->timeSyncHandle));
}
/* Register Callback APIs for Link Change*/
((((ICSS_EMAC_Object *)emachandle->object)->callBackObject).port0LinkCallBack).callBack = (ICSS_EMAC_CallBack)EIP_DLR_TIMESYNC_port0ProcessLinkBrk;
((((ICSS_EMAC_Object *)emachandle->object)->callBackObject).port0LinkCallBack).userArg = (void*)icssEipHandle;
((((ICSS_EMAC_Object *)emachandle->object)->callBackObject).port1LinkCallBack).callBack = (ICSS_EMAC_CallBack)EIP_DLR_TIMESYNC_port1ProcessLinkBrk;
((((ICSS_EMAC_Object *)emachandle->object)->callBackObject).port1LinkCallBack).userArg = (void*)icssEipHandle;
ICSS_EMAC Receive Real-Time (Rx-RT) Callback registration
As described in the QoS section, DLR frames like Sign-on, Neighbor Check Request, Link Status/Neighbor Status frames are sent to the host by the firmware in the highest priority queue. To process these, an RT-Rx callback needs to be assigned to the hook in ICSS_EMAC.
The code below can be used as a reference for this.
/* Register Rx RT callback API */
((((ICSS_EMAC_Object *)emachandle->object)->callBackObject).rxRTCallBack).callBack = (ICSS_EMAC_CallBack)EIP_RtRxCallback;
((((ICSS_EMAC_Object *)emachandle->object)->callBackObject).rxRTCallBack).userArg = (void*)icssEipHandle;
A sample Rx RT callback API for EIP can be referenced below.
/* Global counter to counter Rx RT errors */
static uint32_t rx_rt_errors_s = 0;
/**PTP MAC ID for comparison*/
uint8_t ptpMAC_EIP[6] = {0x1, 0x0, 0x5e, 0x0, 0x1, 0x81};
/**DLR MAC ID for comparison*/
uint8_t dlrMAC_EIP[6] = {0x1, 0x21, 0x6c, 0x0, 0x0, 0x2};
int8_t EIP_RtRxCallback (void *emacHandleVoidPtr, uint8_t portNumber, void * eipHandleVoidPtr)
{
uint32_t packetLen;
int32_t port;
int8_t returnVal = SystemP_SUCCESS;
int32_t queue;
int32_t len;
ICSS_EMAC_RxArgument rxArgs;
EIP_Handle eipHandle = (EIP_Handle)eipHandleVoidPtr;
ICSS_EMAC_Handle emacHandle = (ICSS_EMAC_Handle)emacHandleVoidPtr;
ICSS_EMAC_PortParams rxPort = ((ICSS_EMAC_Object*)(emacHandle->object))->switchPort[0];
uint32_t rxErrors = rxPort.queue[0].qStat.errCount +
rxPort.queue[1].qStat.errCount +
rxPort.queue[2].qStat.errCount;
uint8_t *dstMacId = eipHandle->tempFrame;
packetLen = ICSS_EMAC_rxPktInfo (emacHandle, &port, &queue);
if (packetLen == SystemP_FAILURE)
{
returnVal = SystemP_FAILURE;
return returnVal;
}
if (rxErrors != rx_rt_errors_s)
{
rx_rt_errors_s = rxErrors;
DebugP_log("RX real-time queue errors: %d", rxErrors);
}
switch (queue)
{
case ICSS_EMAC_QUEUE1:
case ICSS_EMAC_QUEUE2:
case ICSS_EMAC_QUEUE3:
case ICSS_EMAC_QUEUE4:
{
rxArgs.icssEmacHandle = emacHandleVoidPtr;
rxArgs.destAddress = (uint32_t)(icssEipHandle->tempFrame);
rxArgs.queueNumber = queue;
rxArgs.more = 0;
rxArgs.port = 0;
len = ICSS_EMAC_rxPktGet (&rxArgs, NULL);
/*Compare Destination MAC ID and determine if this is a DLR packet*/
if((memcmp((void *)dstMacId, (void *)dlrMAC_EIP, 6U) == 0))
{
EIP_DLR_processDLRFrame(eipHandle->dlrHandle, eipHandle->tempFrame,
rxArgs.port - 1, len);
}
/*Compare Destination MAC ID and determine if this is a PTP packet*/
else if((memcmp((void *)dstMacId, (void *)ptpMAC_EIP, 6U) == 0) &&
(rxArgs.port >= ICSS_EMAC_PORT_1) &&
(rxArgs.port <= ICSS_EMAC_PORT_2))
{
/*Link local field doesn't matter in case of EIP*/
TimeSync_processPTPFrame(eipHandle->timeSyncHandle,
eipHandle->tempFrame, rxArgs.port, len, FALSE);
}
} break;
default:
{
returnVal = SystemP_FAILURE;
} break;
}
return returnVal;
}
DLR Interrupt Registration
The ICSS firmware relies on the DLR Driver to handle some parts of the state machine processing. For this, it is very important to ensure that the DLR interrupts are configured correctly in the handle.
The following code can be used as a reference.
/* Interrupt related defines EthernetIP */
#define EIP_PTP_INT_NUM (3)
#define EIP_DLR_P0_INT_OFFSET (1)
#define EIP_DLR_P1_INT_OFFSET (2)
#define EIP_BEACON_TIMEOUT_INT_OFFSET_P0 (4)
#define EIP_BEACON_TIMEOUT_INT_OFFSET_P1 (7)
/*Configure the DLR and PTP Interrupts */
void EIP_configureInterrupts(EIP_DLRHandle dlrHandle, TimeSync_ParamsHandle_t timeSyncHandle)
{
PRUICSS_HwAttrs const *pruicssHwAttrs = PRUICSS_getAttrs(CONFIG_PRU_ICSS1);
if(pruicssHwAttrs->instance == 0)
{
/*Configure Time Sync interrupts*/
timeSyncHandle->timeSyncConfig.txIntNum = CSLR_R5FSS0_CORE0_INTR_PRU_ICSSG0_PR1_HOST_INTR_PEND_0 + EIP_PTP_INT_NUM;
/*Configure DLR*/
dlrHandle->dlrObj->port0IntNum = CSLR_R5FSS0_CORE0_INTR_PRU_ICSSG0_PR1_HOST_INTR_PEND_0 + EIP_DLR_P0_INT_OFFSET;
dlrHandle->dlrObj->port1IntNum = CSLR_R5FSS0_CORE0_INTR_PRU_ICSSG0_PR1_HOST_INTR_PEND_0 + EIP_DLR_P1_INT_OFFSET;
dlrHandle->dlrObj->beaconTimeoutIntNum_P0 = CSLR_R5FSS0_CORE0_INTR_PRU_ICSSG0_PR1_HOST_INTR_PEND_0 + EIP_BEACON_TIMEOUT_INT_OFFSET_P0;
dlrHandle->dlrObj->beaconTimeoutIntNum_P1 = CSLR_R5FSS0_CORE0_INTR_PRU_ICSSG0_PR1_HOST_INTR_PEND_0 + EIP_BEACON_TIMEOUT_INT_OFFSET_P1;
}
else
{
/*Configure Time Sync interrupts*/
timeSyncHandle->timeSyncConfig.txIntNum = CSLR_R5FSS0_CORE0_INTR_PRU_ICSSG1_PR1_HOST_INTR_PEND_0 + EIP_PTP_INT_NUM;
/*Configure DLR*/
dlrHandle->dlrObj->port0IntNum = CSLR_R5FSS0_CORE0_INTR_PRU_ICSSG1_PR1_HOST_INTR_PEND_0 + EIP_DLR_P0_INT_OFFSET;
dlrHandle->dlrObj->port1IntNum = CSLR_R5FSS0_CORE0_INTR_PRU_ICSSG1_PR1_HOST_INTR_PEND_0 + EIP_DLR_P1_INT_OFFSET;
dlrHandle->dlrObj->beaconTimeoutIntNum_P0 = CSLR_R5FSS0_CORE0_INTR_PRU_ICSSG1_PR1_HOST_INTR_PEND_0 + EIP_BEACON_TIMEOUT_INT_OFFSET_P0;
dlrHandle->dlrObj->beaconTimeoutIntNum_P1 = CSLR_R5FSS0_CORE0_INTR_PRU_ICSSG1_PR1_HOST_INTR_PEND_0 + EIP_BEACON_TIMEOUT_INT_OFFSET_P1;
}
}