This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Hello,
I need your help to start DLR on the AM243X (TMDS243EVM) evaluation Board, please see below the description:
Test 1 : On TI Eval board (AM243x) with SDK 8.6.0.45 + “TI EIP Sample (mcu_plus_sdk_am243x_08_06_00_45\source\industrial_comms\ethernetip_adapter)” => DLR Tests OK
Test 2 : On TI Eval board (AM243x) with SDK 8.6.0.45 + “TI ICSS_DLR ” => "dlrStruct" is not refreshed correctly (SMVariables.topology stay in “Linear”) and the DLR Node seems not working well.
I have added the Industrial comms module:
Our project will use the icss_dlr.c …files.
To initialize the DLR, I have modified the file “hsr_prp_main.c” to call EIP_drvInit() + EIP_drvStart().
Can you take a look to see if something wrong is the “hsr_prp_main.c”, do you know if we need to configure some specific parameter for DLR in sysconfig ?
Thanks for your help,
Jean-Yves from Molex
/* * Copyright (C) 2021 Texas Instruments Incorporated * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the * distribution. * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* ========================================================================== */ /* Include Files */ /* ========================================================================== */ #include <stdio.h> #include <stdbool.h> #include <string.h> #include "tiswitch_pruss_intc_mapping.h" #include <hsr_prp_soc.h> #include <networking/icss_emac/icss_emac.h> #include "ti_board_open_close.h" #include "ti_drivers_open_close.h" #include "ti_drivers_config.h" #include "ti_board_config.h" #include <industrial_comms/hsr_prp/icss_fwhal/hsrPrp_firmwareOffsets.h> #ifdef ICSS_PROTOCOL_RED #include <industrial_comms/hsr_prp/icss_fwhal/hsrPrp_red_nodeTable.h> #include <industrial_comms/hsr_prp/icss_fwhal/hsrPrp_red_snmp.h> #include <industrial_comms/hsr_prp/icss_fwhal/hsrPrp_red_statistics.h> #include <industrial_comms/hsr_prp/icss_fwhal/hsrPrp_red.h> #include <industrial_comms/hsr_prp/icss_fwhal/hsrPrp_handle.h> #include <industrial_comms/hsr_prp/icss_fwhal/hsrPrp_red_multicastTable.h> #include <industrial_comms/hsr_prp/icss_fwhal/hsrPrp_red_vlanTable.h> #endif /* ICSS_PROTOCOL_RED */ #include <industrial_comms/hsr_prp/icss_fwhal/hsrPrp_red_config.h> #include <industrial_comms/hsr_prp/icss_fwhal/firmware/icss_emac_mmap.h> #include <networking/icss_emac/lwipif/inc/lwip2icss_emac.h> #include <drivers/mdio.h> /*--------------------------Stack Related Includes----------------------------*/ #include "lwip/tcpip.h" #include "lwip/dhcp.h" #include "lwip/autoip.h" #include "default_netif.h" /* include the port-dependent configuration */ #include "hsr_prp_lwipcfg.h" #include "examples/lwiperf/lwiperf_example.h" /*--------------------------EIP sacnner realted includes----------------------------*/ #include "sample_main.h" #include "scan_config.h" #include "eip_types.h" #include "user_so.h" #include "FreeRTOS.h" #include "task.h" #include <board/led.h> #include "ti_drivers_config.h" #include "drivers/gpio.h" #include <industrial_comms/ethernetip_adapter/icss_fwhal/icss_eip_driver.h> #include <industrial_comms/ethernetip_adapter/icss_fwhal/icss_switch_dlr.h> #define MAIN_TASK_PRI (configMAX_PRIORITIES-1) #define MAIN_TASK_SIZE (16384U/sizeof(configSTACK_DEPTH_TYPE)) StackType_t gMainTaskStack[MAIN_TASK_SIZE] __attribute__((aligned(32))); StaticTask_t gMainTaskObj; TaskHandle_t gMainTask; /* ========================================================================== */ /* Macros & Typedefs */ /* ========================================================================== */ #define PCP_2_QUEUE_MAP_SIZE 4 #define LWIPINIT_TASK_PRIORITY (8) #define LWIPINIT_TASK_STACK_SIZE (0x4000) #define EIP_DLR_P0_INT_NUM CSLR_R5FSS0_CORE0_INTR_PRU_ICSSG1_PR1_HOST_INTR_PEND_0 + 1 //248 + 1 (ARM interrupt number on AM243x) #define EIP_DLR_P1_INT_NUM CSLR_R5FSS0_CORE0_INTR_PRU_ICSSG1_PR1_HOST_INTR_PEND_0 + 2 #define EIP_BEACON_TIMEOUT_INT_NUM_P0 CSLR_R5FSS0_CORE0_INTR_PRU_ICSSG1_PR1_HOST_INTR_PEND_0 + 4 #define EIP_BEACON_TIMEOUT_INT_NUM_P1 CSLR_R5FSS0_CORE0_INTR_PRU_ICSSG1_PR1_HOST_INTR_PEND_0 + 7 /* ========================================================================== */ /* Global Variables */ /* ========================================================================== */ TaskP_Object taskLwipInitObject; uint32_t gtaskLwipInitStack[LWIPINIT_TASK_STACK_SIZE/sizeof(uint32_t)] __attribute__((aligned(32))); /** * Default PCP to Q mapping. See description of function hsrprp_initializePCPtoQueueMap below */ uint8_t default_pcp_2_queue_map[PCP_2_QUEUE_MAP_SIZE] = {ICSS_EMAC_QUEUE4, ICSS_EMAC_QUEUE3, ICSS_EMAC_QUEUE2, ICSS_EMAC_QUEUE1}; /** \brief PRU-ICSS LLD handle */ PRUICSS_Handle prusshandle; /** \brief ICSSEmac LLD handle */ ICSS_EMAC_Handle emachandle; /** \brief Time Sync handle */ TimeSync_ParamsHandle_t timeSyncHandle; /** \brief hsrprp handle */ hsrPrpHandle *hsrPrphandle; /** \brief LwIP Interface layer handle */ Lwip2Emac_Handle Lwipif_handle; uint8_t lclMac[6]; uint32_t ipAddress; int collision_pkt_dropped; int num_of_collision_occured; /*-----------------------Stack Global Variable--------------------*/ struct dhcp netif_dhcp; struct autoip netif_autoip; /*-----------------------PTP global variables---------------------*/ /**When clock goes into sync for very timeset this*/ uint8_t deviceInSync = 0; /**If clock goes out of sync and dut was in sync then set this*/ uint8_t ptpError = 0; /*SN : New implementation */ dlrStruct gEipDlrStruct; /** EIP driver handle */ EIP_Handle icssEipHandle; /** EIP DLR driver handle */ EIP_DLRHandle dlrHandle; /**PTP MAC ID for comparison*/ uint8_t timeSyncMAC[6] = {0x1, 0x1b, 0x19, 0x0, 0x0, 0x0}; uint8_t linkLocalMAC[6] = {0x1, 0x80, 0xc2, 0x0, 0x0, 0xE}; /**Temporary placeholder to copy packets*/ uint8_t tempFrame[ICSS_EMAC_MAXMTU]__attribute__((aligned(32))); /* ========================================================================== */ /* Function Declarations */ /* ========================================================================== */ /** * @brief Initialize the PCP to Queue Map to default value * i.e. Queue 4 or lowest priority queue * * @param emachandle Pointer to EMAC handle. Used to fetch shared RAM base address * * @return none */ void hsrprp_initializePCPtoQueueMap(ICSS_EMAC_Handle emachandle); /** * @brief Load the PCP to Queue Map to shared RAM. * The firmware uses this to * * @param emachandle Pointer to EMAC handle. Used to fetch shared RAM base address * @param pcp_2_queue_map pointer to PCP to Q mapping. * * The mapping is very simple. The memory is an 4 bytes char array * with each byte containing the queue. The index of the byte corresponds to the * PCP value. Here lower value is higher priority queue, see default_pcp_2_queue_map for example * So we have as an example (see default_pcp_2_queue_map) * PCP Queue Mem Offset (QUEUE_2_PCP_MAP_OFFSET is base) * 0 Q4 0 * 1 Q4 0 * 2 Q3 1 * ... * ... * 7 Q1 3 * * @return none */ void hsrprp_loadPCPtoQueueMap(ICSS_EMAC_Handle emachandle, uint8_t *pcp_2_queue_map); /*This is kept in application for now*/ /*RT frames are processed here including PTP frames*/ void hsrprp_processHighPrioFrames(void *icssEmacHandle, void *queue_number, void *userArg); /** * @brief Function to initialize the PTP driver handle * * Does Memory allocation, EDMA param configuration * * * @param timeSyncHandle [in] PTP driver handle * @param emachandle [in] EMAC LLD handle * * @retval Error status * */ int8_t hsrprp_initICSSPtpHandle(TimeSync_ParamsHandle_t timeSyncHandle, ICSS_EMAC_Handle emachandle); /** * @brief Function to initialize the HSR/PRP driver handle * * Implemented to facilitate multi-instance capability. * Moving all global variables across the driver files to this handle in hsrPrp_handle.h file * * @param hsrPrpHandle [in] HSR driver handle * * @retval none * */ void hsrPrp_handleInit(hsrPrpHandle *hsrPrphandle); /** * @brief Function to register the Port 1 LinkReset callback * * @param linkStatus [in] link status * @param arg2 [in] pointer to a handle * * @retval none * */ void hsrPrp_Port1linkResetCallBack(void *icssEmacHandle, void *linkStatus, void *userArg); /** * @brief Function to register the Port 2 LinkReset callback * * @param linkStatus [in] link status * @param arg2 [in] pointer to a handle * * @retval none * */ void hsrPrp_Port2linkResetCallBack(void *icssEmacHandle, void *linkStatus, void *userArg); /** * @brief Function to get ICSS EMAC handle info * * Implemented to provide LwIP interface layer info about the EMAC Handle from application * * @param hLwip2emac [in] Lwip2emac Handle * * @retval SystemP_SUCCESS * SystemP_FALIURE * */ int32_t app_getEmacHandle(Lwip2Emac_Handle hLwip2Emac); /** * @brief This function initializes this lwIP test. When NO_SYS=1, this is done in * the main_loop context (there is no other one), when NO_SYS=0, this is done * in the tcpip_thread context * * @param none None * * @retval none * */ void hsrprp_LwipInitStack(); static void hsrprp_LwipTest_init(void * arg); static void hsrprp_LwipTest_netif_init(void); static void hsrprp_LwipApps_init(void); static void hsrprp_LwipStatus_callback(struct netif *state_netif); static void hsrprp_LwipLink_callback(struct netif *state_netif); extern void Lwip2Emac_getHandle(Lwip2Emac_Handle *AppLwipHandle); static int32_t hsrprp_LoadFirmware(void); /* ========================================================================== */ /* Function Definitions */ /* ========================================================================== */ static int isValidIP(const char *ip_str) { unsigned int n1, n2, n3, n4; if(sscanf(ip_str, "%u.%u.%u.%u", &n1, &n2, &n3, &n4) != 4) { return FALSE; } if((n1 != 0) && (n1 <= 255) && (n2 <= 255) && (n3 <= 255) && (n4 <= 255)) { char buf[64]; sprintf(buf, "%u.%u.%u.%u", n1, n2, n3, n4); if(strcmp(buf, ip_str)) { return 0; } return TRUE; } return FALSE; } static void changeIPEndianness(uint32_t *dwIPAddress) { uint32_t dwTempIP; dwTempIP = * dwIPAddress << 24; dwTempIP |= (* dwIPAddress & 0xFF00) << 8; dwTempIP |= (* dwIPAddress & 0xFF0000) >> 8; dwTempIP |= (* dwIPAddress & 0xFF000000) >> 24; * dwIPAddress = dwTempIP; } /** * @brief Function which calls an API in the event of a synchronization loss * * @retval None */ void hsrprp_syncLossCallback() { /*This indicates a loss of time sync Call your function here which handles sync loss*/ return; } /** * @brief Function which resets TAS in the event of a synchronization loss * * @retval None */ uint8_t hsrprp_AppGPTPSynchronized() { if(timeSyncHandle->tsRunTimeVar->stateMachine & TS_STATE_MACHINE_DEVICE_IN_SYNC) { return TRUE; } else { return FALSE; } } /** * @brief main task to initialize the stack * * @param args not used * * @return none */ void taskLwip(void *args) { hsrprp_LwipInitStack(); TaskP_destruct(&taskLwipInitObject); } uint8_t addIPAddress(uint32_t dwIPAddress) { sys_lock_tcpip_core(); netif_set_ipaddr(Lwipif_handle->netif, (ip4_addr_t *)&dwIPAddress); sys_unlock_tcpip_core(); return 1; } void EIP_syncLossCallback() { /*This indicates a loss of time sync Call your function here which handles sync loss*/ return; } int8_t EIP_initICSSPtpHandle(TimeSync_ParamsHandle_t timeSyncHandle, ICSS_EMAC_Handle emachandle) { int8_t returnVal = SystemP_FAILURE; timeSyncHandle->emacHandle = emachandle; /*Configure PTP. These variables must be configured before doing anything else*/ timeSyncHandle->timeSyncConfig.config = BOTH; timeSyncHandle->timeSyncConfig.type = E2E; timeSyncHandle->timeSyncConfig.protocol = UDP_IPV4; timeSyncHandle->timeSyncConfig.tickPeriod = 500; timeSyncHandle->txprotocol = 0; timeSyncHandle->tsSyntInfo = (timeSync_SyntInfo_t *)malloc(sizeof( timeSync_SyntInfo_t)); if(timeSyncHandle->tsSyntInfo == NULL) { DebugP_log("\n\rIssue in allocating memory for timeSyncHandle->tsSyntInfo"); } timeSyncHandle->tsNrrInfo[0] = (timeSync_NrrInfo_t *)malloc(sizeof( timeSync_NrrInfo_t)); if(timeSyncHandle->tsNrrInfo[0] == NULL) { DebugP_log("\n\rIssue in allocating memory for timeSyncHandle->tsNrrInfo[0]"); } timeSyncHandle->tsNrrInfo[1] = (timeSync_NrrInfo_t *)malloc(sizeof( timeSync_NrrInfo_t)); if(timeSyncHandle->tsNrrInfo[1] == NULL) { DebugP_log("\n\rIssue in allocating memory for timeSyncHandle->tsNrrInfo[1]"); } timeSyncHandle->syncParam[0] = (syncParam_t *)malloc(sizeof(syncParam_t)); if(timeSyncHandle->syncParam[0] == NULL) { DebugP_log("\n\rIssue in allocating memory for timeSyncHandle->syncParam[0]"); } timeSyncHandle->syncParam[1] = (syncParam_t *)malloc(sizeof(syncParam_t)); if(timeSyncHandle->syncParam[1] == NULL) { DebugP_log("\n\rIssue in allocating memory for timeSyncHandle->syncParam[1]"); } timeSyncHandle->tsRunTimeVar = (timeSync_RuntimeVar_t *)malloc(sizeof( timeSync_RuntimeVar_t)); if(timeSyncHandle->tsRunTimeVar == NULL) { DebugP_log("\n\rIssue in allocating memory for timeSyncHandle->tsRunTimeVar"); } timeSyncHandle->delayParams = (delayReqRespParams_t *)malloc(sizeof( delayReqRespParams_t)); if(timeSyncHandle->delayParams == NULL) { DebugP_log("\n\rIssue in allocating memory for timeSyncHandle->delayParams"); } timeSyncHandle->offsetAlgo = (timeSync_Offset_Stable_Algo_t *)malloc(sizeof( timeSync_Offset_Stable_Algo_t)); if(timeSyncHandle->offsetAlgo == NULL) { DebugP_log("\n\rIssue in allocating memory for timeSyncHandle->offsetAlgo"); } /*Allocate Rx and Tx packet buffers*/ returnVal = TimeSync_alloc_PktBuffer(timeSyncHandle); /*Set only if a custom Tx LLD API is used*/ timeSyncHandle->timeSyncConfig.custom_tx_api = 0; /*Set to 1 if Rx timestamps are coming from shared RAM*/ timeSyncHandle->timeSyncConfig.timestamp_from_shared_ram = 1; /*If there is no forwarding between ports then set this*/ timeSyncHandle->timeSyncConfig.emac_mode = 0; timeSyncHandle->timeSyncConfig.hsrEnabled = 0; timeSyncHandle->rxTimestamp_gPTP = (timeStamp *)malloc(sizeof(timeStamp)); timeSyncHandle->timeSyncConfig.domainNumber[0] = 0; timeSyncHandle->timeSyncConfig.logAnnounceRcptTimeoutInterval = DEFAULT_ANNOUNCE_TIMEOUT_LOG_INTERVAL; timeSyncHandle->timeSyncConfig.logAnnounceSendInterval = DEFAULT_ANNOUNCE_SEND_LOG_INTERVAL; timeSyncHandle->timeSyncConfig.logPDelReqPktInterval = DEFAULT_PDELAY_REQ_LOG_INTERVAL; timeSyncHandle->timeSyncConfig.logSyncInterval = DEFAULT_SYNC_SEND_LOG_INTERVAL; /*No asymmetry*/ timeSyncHandle->timeSyncConfig.asymmetryCorrection[0] = 0; timeSyncHandle->timeSyncConfig.asymmetryCorrection[1] = 0; timeSyncHandle->timeSyncConfig.pdelayBurstNumPkts = 3; /*3 frames sent in a burst*/ timeSyncHandle->timeSyncConfig.pdelayBurstInterval = 200; /*gap between each frame is 100ms*/ timeSyncHandle->timeSyncConfig.sync0_interval = 1000000; /*1 milisec value*/ /*Register callback*/ timeSyncHandle->timeSyncConfig.timeSyncSyncLossCallBackfn = (TimeSync_SyncLossCallBack_t)EIP_syncLossCallback; timeSyncHandle->timeSyncConfig.masterParams.priority1 = TIMESYNC_DEFAULT_PRIO_1; timeSyncHandle->timeSyncConfig.masterParams.priority2 = TIMESYNC_DEFAULT_PRIO_2; timeSyncHandle->timeSyncConfig.masterParams.clockAccuracy = TIMESYNC_DEFAULT_CLOCK_ACCURACY; /*greater than 10s */ timeSyncHandle->timeSyncConfig.masterParams.clockClass = TIMESYNC_DEFAULT_CLOCK_CLASS; timeSyncHandle->timeSyncConfig.masterParams.clockVariance = TIMESYNC_DEFAULT_CLOCK_VARIANCE; timeSyncHandle->timeSyncConfig.masterParams.stepRemoved = TIMESYNC_DEFAULT_STEPS_REMOVED; timeSyncHandle->timeSyncConfig.masterParams.UTCOffset = TIMESYNC_UTC_OFFSET; timeSyncHandle->timeSyncConfig.masterParams.timeSource = TIMESYNC_DEFAULT_TIME_SOURCE; /*Internal oscillator*/ timeSyncHandle->timeSyncConfig.masterParams.ptp_flags[TS_PTP_TIMESCALE_INDEX] = 1; timeSyncHandle->timeSyncConfig.masterParams.ptp_flags[TS_PTP_TWO_STEP_INDEX] = 1; returnVal = SystemP_SUCCESS; return returnVal; } void EIP_initICSSDlrHandle(EIP_DLRHandle dlrHandle, ICSS_EMAC_Handle emachandle) { dlrHandle->emacHandle = emachandle; // dlrHandle->dlrObj = (dlrStruct *)malloc(sizeof(dlrStruct)); dlrHandle->dlrObj = &gEipDlrStruct; dlrHandle->exclusionList = (exceptionList *)malloc(sizeof(exceptionList)); } int8_t EIP_initDefaultValues(EIP_Handle icssEipHandle,ICSS_EMAC_Handle emachandle,PRUICSS_Handle prusshandle) { int8_t status = SystemP_SUCCESS; /* Memory allocations */ memset(icssEipHandle,0,sizeof(struct eip_Config_s)); icssEipHandle->emacHandle = emachandle; icssEipHandle->pruicssHandle = prusshandle; dlrHandle = (EIP_DLRHandle)malloc(sizeof(dlr_Config)); timeSyncHandle = (TimeSync_ParamsHandle_t)malloc(sizeof(TimeSync_ParamsHandle)); EIP_initICSSDlrHandle(dlrHandle, emachandle); status = EIP_initICSSPtpHandle(timeSyncHandle, emachandle); return status; } /** * \brief the application entry point - initializes low level hardware & creates tasks * */ int hsr_prp_main() { TaskP_Params taskParams; uint32_t status = SystemP_FAILURE; PRUICSS_IntcInitData pruss_intc_initdata = PRUSS_INTC_INITDATA; ICSS_EMAC_Params icssEmacParams; Drivers_open(); status = Board_driversOpen(); DebugP_assert(status==SystemP_SUCCESS); prusshandle = PRUICSS_open(CONFIG_PRU_ICSS1); DebugP_assert(prusshandle != NULL); #ifdef MDIO_MANUAL_MODE_ENABLED mdioManualModeSetup(); #endif /*Creating hsrPrp Handle*/ hsrPrphandle = (hsrPrpHandle *)malloc(sizeof(hsrPrpHandle)); DebugP_assert(hsrPrphandle != NULL); /*Getting Lwip2EmacHandle for interface layer*/ Lwip2Emac_getHandle(&Lwipif_handle); #ifdef HSR_PRP_RGMII hsrprp_rgmii_init(); DebugP_log("Mode: RGMII\n"); #else hsrprp_mii_init(); DebugP_log("Mode: MII\n"); #endif ICSS_EMAC_Params_init(&icssEmacParams); icssEmacParams.pruicssIntcInitData = &pruss_intc_initdata; icssEmacParams.fwStaticMMap = &(icss_emacFwStaticCfgLocal[1]); icssEmacParams.fwDynamicMMap = &icss_emacFwDynamicCfgLocal; icssEmacParams.pruicssHandle = prusshandle; icssEmacParams.callBackObject.rxRTCallBack.callBack = (ICSS_EMAC_CallBack)Lwip2Emac_serviceRx; icssEmacParams.callBackObject.rxRTCallBack.userArg = (void*)(Lwipif_handle); icssEmacParams.callBackObject.rxNRTCallBack.callBack = (ICSS_EMAC_CallBack)Lwip2Emac_serviceRx; icssEmacParams.callBackObject.rxNRTCallBack.userArg = (void*)(Lwipif_handle); icssEmacParams.callBackObject.customRxCallBack.callBack = NULL; icssEmacParams.callBackObject.customRxCallBack.userArg = NULL; icssEmacParams.ethphyHandle[0] = gEthPhyHandle[CONFIG_ETHPHY0]; icssEmacParams.ethphyHandle[1] = gEthPhyHandle[CONFIG_ETHPHY1]; hsrprp_socgetMACAddress(lclMac); memcpy(&(icssEmacParams.macId[0]), &(lclMac[0]), 6); emachandle = ICSS_EMAC_open(CONFIG_ICSS_EMAC0, &icssEmacParams); DebugP_assert(emachandle != NULL); icssEipHandle = (EIP_Handle)malloc(sizeof(struct eip_Config_s)); if(NULL == icssEipHandle) { DebugP_log("Task Creation failed\r\n"); } /*Configure interrupts*/ hsrprp_configureInterrupts(emachandle); hsrPrp_handleInit(hsrPrphandle); /* Initializing HSR handle */ status = EIP_initDefaultValues(icssEipHandle,emachandle,prusshandle); DebugP_assert(status==SystemP_SUCCESS); icssEipHandle->dlrHandle = dlrHandle; icssEipHandle->timeSyncHandle = timeSyncHandle; EIP_drvInit(icssEipHandle); EIP_drvStart(icssEipHandle); DebugP_log("Ethernet/IP Firmware Load Done\r\n"); status = hsrprp_LoadFirmware(); /* Load Firmware */ printf("STATUS : %d \n",status); if(status == SystemP_SUCCESS) { /*Load the default PCP to Queue mapping*/ hsrprp_loadPCPtoQueueMap(emachandle, default_pcp_2_queue_map); } TaskP_Params_init(&taskParams); taskParams.priority = LWIPINIT_TASK_PRIORITY; /* we need stack prio higher than LED I/O*/ taskParams.stackSize = LWIPINIT_TASK_STACK_SIZE; taskParams.stack = (uint8_t *)gtaskLwipInitStack; taskParams.name = "LwipInitTask"; taskParams.taskMain = (TaskP_FxnMain)taskLwip; status = TaskP_construct(&taskLwipInitObject, &taskParams); if(status != SystemP_SUCCESS) { DebugP_log("LwipInitTask Creation failed\r\n"); } /* Wait for PRU load complete */ ClockP_usleep(ClockP_ticksToUsec(5000)); // Set MOD LED Steady GREEN (L26) GPIO_pinWriteHigh((uint32_t)AddrTranslateP_getLocalAddr(CONFIG_GPIO0_BASE_ADDR), CONFIG_GPIO0_PIN); oled_start(); DebugP_log("\n\rInit scanner\n\r"); int returnValue = user_eip_scanner_init(emachandle); if(returnValue != 1) { DebugP_log("user_eip_scanner_start failed %d\r\n", returnValue); } else { DebugP_log("user_eip_scanner_start is success \r\n"); } return status; } void hsrprp_processHighPrioFrames(void *icssEmacHandle, void *queue_number, void *userArg) { int16_t size = 0; ICSS_EMAC_RxArgument rxArg; uint8_t *dstMacId; ICSS_EMAC_Handle hsrIcssEmacHandle = timeSyncHandle->emacHandle; rxArg.icssEmacHandle = hsrIcssEmacHandle; rxArg.destAddress = (uint32_t)(tempFrame); rxArg.more = 0; rxArg.queueNumber = (uint32_t)queue_number; rxArg.port = 0; size = (uint16_t)ICSS_EMAC_rxPktGet(&rxArg, &userArg); dstMacId = tempFrame; if(memcmp(dstMacId, timeSyncMAC, 6U) == 0) { TimeSync_processPTPFrame(timeSyncHandle, tempFrame, rxArg.port, size, 0); } else if(memcmp(dstMacId, linkLocalMAC, 6U) == 0) { TimeSync_processPTPFrame(timeSyncHandle, tempFrame, rxArg.port, size, 1); } else { parseAndCheckHSRPRPTestFrame(tempFrame); } } void freertos_main(void *args) { hsr_prp_main(); vTaskDelete(NULL); } int main(void) { /* init SOC specific modules */ System_init(); // Board_init(BOARD_INIT_PINMUX_CONFIG | BOARD_INIT_MODULE_CLOCK | BOARD_INIT_UART_STDIO); Board_init(); /* This task is created at highest priority, it should create more tasks and then delete itself */ gMainTask = xTaskCreateStatic( freertos_main, /* Pointer to the function that implements the task. */ "freertos_main", /* Text name for the task. This is to facilitate debugging only. */ MAIN_TASK_SIZE, /* Stack depth in units of StackType_t typically uint32_t on 32b CPUs */ NULL, /* We are not using the task parameter. */ MAIN_TASK_PRI, /* task priority, 0 is lowest priority, configMAX_PRIORITIES-1 is highest */ gMainTaskStack, /* pointer to stack base */ &gMainTaskObj ); /* pointer to statically allocated task object memory */ configASSERT(gMainTask != NULL); /* Start the scheduler to start the tasks executing. */ vTaskStartScheduler(); /* The following line should never be reached because vTaskStartScheduler() will only return if there was not enough FreeRTOS heap memory available to create the Idle and (if configured) Timer tasks. Heap management, and techniques for trapping heap exhaustion, are described in the book text. */ DebugP_assertNoLog(0); return 0; } /** * @brief Function to initialize the PTP driver handle * * Does Memory allocation, EDMA param configuration * * * @param timeSyncHandle [in] PTP driver handle * @param emachandle [in] EMAC LLD handle * * @retval Error status * */ int8_t hsrprp_initICSSPtpHandle(TimeSync_ParamsHandle_t timeSyncHandle, ICSS_EMAC_Handle emachandle) { int8_t returnVal = TIME_SYNC_OK; /*Configure PTP. These variables must be configured before doing anything else*/ timeSyncHandle->timeSyncConfig.config = BOTH; timeSyncHandle->timeSyncConfig.type = P2P; timeSyncHandle->timeSyncConfig.protocol = IEEE_802_3; timeSyncHandle->timeSyncConfig.tickPeriod = 1000; timeSyncHandle->txprotocol = 0; timeSyncHandle->tsSyntInfo = (timeSync_SyntInfo_t *)malloc(sizeof( timeSync_SyntInfo_t)); if(timeSyncHandle->tsSyntInfo == NULL) { return TIME_SYNC_UNABLE_TO_ALLOC_MEM; } timeSyncHandle->tsNrrInfo[0] = (timeSync_NrrInfo_t *)malloc(sizeof( timeSync_NrrInfo_t)); if(timeSyncHandle->tsNrrInfo[0] == NULL) { return TIME_SYNC_UNABLE_TO_ALLOC_MEM; } timeSyncHandle->tsNrrInfo[1] = (timeSync_NrrInfo_t *)malloc(sizeof( timeSync_NrrInfo_t)); if(timeSyncHandle->tsNrrInfo[1] == NULL) { return TIME_SYNC_UNABLE_TO_ALLOC_MEM; } timeSyncHandle->syncParam[0] = (syncParam_t *)malloc(sizeof(syncParam_t)); if(timeSyncHandle->syncParam[0] == NULL) { return TIME_SYNC_UNABLE_TO_ALLOC_MEM; } timeSyncHandle->syncParam[1] = (syncParam_t *)malloc(sizeof(syncParam_t)); if(timeSyncHandle->syncParam[1] == NULL) { return TIME_SYNC_UNABLE_TO_ALLOC_MEM; } timeSyncHandle->tsRunTimeVar = (timeSync_RuntimeVar_t *)malloc(sizeof( timeSync_RuntimeVar_t)); if(timeSyncHandle->tsRunTimeVar == NULL) { return TIME_SYNC_UNABLE_TO_ALLOC_MEM; } timeSyncHandle->delayParams = (delayReqRespParams_t *)malloc(sizeof( delayReqRespParams_t)); if(timeSyncHandle->delayParams == NULL) { return TIME_SYNC_UNABLE_TO_ALLOC_MEM; } timeSyncHandle->offsetAlgo = (timeSync_Offset_Stable_Algo_t *)malloc(sizeof( timeSync_Offset_Stable_Algo_t)); if(timeSyncHandle->offsetAlgo == NULL) { return TIME_SYNC_UNABLE_TO_ALLOC_MEM; } /*Allocate Rx and Tx packet buffers*/ returnVal = TimeSync_alloc_PktBuffer(timeSyncHandle); if(returnVal != TIME_SYNC_OK) { return TIME_SYNC_UNABLE_TO_ALLOC_MEM; } /*Set only if a custom Tx LLD API is used*/ timeSyncHandle->timeSyncConfig.custom_tx_api = 0; /*Set to 1 if Rx timestamps are coming from shared RAM, Set to 0 if Rx timestamps are coming from packet itself*/ timeSyncHandle->timeSyncConfig.timestamp_from_shared_ram = 0; #ifdef ICSS_PROTOCOL_HSR /*Enable only for HSR*/ timeSyncHandle->timeSyncConfig.hsrEnabled = 1; /*If there is no forwarding between ports then set this*/ timeSyncHandle->timeSyncConfig.emac_mode = 0; #endif /*HSR*/ #ifdef ICSS_PROTOCOL_PRP timeSyncHandle->timeSyncConfig.hsrEnabled = 0; timeSyncHandle->timeSyncConfig.emac_mode = 1; #endif /*PRP*/ timeSyncHandle->rxTimestamp_gPTP = (timeStamp *)malloc(sizeof(timeStamp)); timeSyncHandle->timeSyncConfig.domainNumber[0] = 0; timeSyncHandle->timeSyncConfig.logAnnounceRcptTimeoutInterval = DEFAULT_ANNOUNCE_TIMEOUT_LOG_INTERVAL; timeSyncHandle->timeSyncConfig.logAnnounceSendInterval = DEFAULT_ANNOUNCE_SEND_LOG_INTERVAL; timeSyncHandle->timeSyncConfig.logPDelReqPktInterval = DEFAULT_PDELAY_REQ_LOG_INTERVAL; timeSyncHandle->timeSyncConfig.logSyncInterval = DEFAULT_SYNC_SEND_LOG_INTERVAL; /*No asymmetry*/ timeSyncHandle->timeSyncConfig.asymmetryCorrection[0] = 0; timeSyncHandle->timeSyncConfig.asymmetryCorrection[1] = 0; timeSyncHandle->timeSyncConfig.pdelayBurstNumPkts = 3; /*3 frames sent in a burst*/ timeSyncHandle->timeSyncConfig.pdelayBurstInterval = 200; /*gap between each frame is 100ms*/ timeSyncHandle->timeSyncConfig.sync0_interval = 1000000; /*1 milisec value*/ /*Register callback*/ timeSyncHandle->timeSyncConfig.timeSyncSyncLossCallBackfn = (TimeSync_SyncLossCallBack_t)hsrprp_syncLossCallback; /*Configure Master params*/ timeSyncHandle->timeSyncConfig.masterParams.priority1 = TIMESYNC_DEFAULT_PRIO_1; timeSyncHandle->timeSyncConfig.masterParams.priority2 = TIMESYNC_DEFAULT_PRIO_2; timeSyncHandle->timeSyncConfig.masterParams.clockAccuracy = TIMESYNC_DEFAULT_CLOCK_ACCURACY; /*greater than 10s */ timeSyncHandle->timeSyncConfig.masterParams.clockClass = TIMESYNC_DEFAULT_CLOCK_CLASS; timeSyncHandle->timeSyncConfig.masterParams.clockVariance = TIMESYNC_DEFAULT_CLOCK_VARIANCE; timeSyncHandle->timeSyncConfig.masterParams.stepRemoved = TIMESYNC_DEFAULT_STEPS_REMOVED; timeSyncHandle->timeSyncConfig.masterParams.UTCOffset = TIMESYNC_UTC_OFFSET; timeSyncHandle->timeSyncConfig.masterParams.timeSource = TIMESYNC_DEFAULT_TIME_SOURCE; /*Internal oscillator*/ timeSyncHandle->timeSyncConfig.masterParams.ptp_flags[TS_PTP_TIMESCALE_INDEX] = 1; timeSyncHandle->timeSyncConfig.masterParams.ptp_flags[TS_PTP_TWO_STEP_INDEX] = 1; #ifdef HSR_PRP_RGMII timeSyncHandle->timeSyncConfig.rxPhyLatency = 534; timeSyncHandle->timeSyncConfig.txPhyLatency = 408; #else timeSyncHandle->timeSyncConfig.rxPhyLatency = 220; timeSyncHandle->timeSyncConfig.txPhyLatency = 64; #endif timeSyncHandle->timeSyncConfig.delayReqSendTaskPriority = 10; timeSyncHandle->timeSyncConfig.txTsTaskPriority = 10; timeSyncHandle->timeSyncConfig.nrtTaskPriority = 8; timeSyncHandle->timeSyncConfig.backgroundTaskPriority = 7; return TIME_SYNC_OK; } /*Initialize the PCP 2 Q mapping to 0 before starting firmware*/ void hsrprp_initializePCPtoQueueMap(ICSS_EMAC_Handle emachandle) { uint8_t *bytePtr = (uint8_t *)((((PRUICSS_HwAttrs const *)(prusshandle->hwAttrs))->sharedDramBase) + QUEUE_2_PCP_MAP_OFFSET); memset(bytePtr, ICSS_EMAC_QUEUE4, PCP_2_QUEUE_MAP_SIZE); } /*Initialize the PCP 2 Q mapping to the required values*/ void hsrprp_loadPCPtoQueueMap(ICSS_EMAC_Handle emachandle, uint8_t *pcp_2_queue_map) { uint8_t *bytePtr = (uint8_t *)((((PRUICSS_HwAttrs const *)(prusshandle->hwAttrs))->sharedDramBase) + QUEUE_2_PCP_MAP_OFFSET); memcpy(bytePtr, pcp_2_queue_map, PCP_2_QUEUE_MAP_SIZE); } void hsrPrp_handleInit(hsrPrpHandle *hsrPrphandle) { hsrPrphandle->redSeqNr = 0; hsrPrphandle->supSeqNr = 0; hsrPrphandle->collision_pkt_dropped = &collision_pkt_dropped; hsrPrphandle->num_of_collision_occured = &num_of_collision_occured; hsrPrphandle->redPruCheckTimerHostTableFlag = 0; hsrPrphandle->redSupFrame = NULL; hsrPrphandle->icssEmacHandle = emachandle; hsrPrphandle->indexArrayBase = (RED_INDEX_ARRAY_ENTRY *)((((PRUICSS_HwAttrs const *)(prusshandle->hwAttrs))->sharedDramBase) + INDEX_ARRAY_NT); hsrPrphandle->binArrayBase = (RED_BIN_ARRAY_ENTRY *)((((PRUICSS_HwAttrs const *)(prusshandle->hwAttrs))->sharedDramBase) + BIN_ARRAY); hsrPrphandle->nodeTableBase = (RED_NODE_TABLE_ENTRY *)((((PRUICSS_HwAttrs const *)(prusshandle->hwAttrs))->sharedDramBase) + NODE_TABLE_NT); } void hsrPrp_Port1linkResetCallBack(void *icssEmacHandle, void *linkStatus, void *userArg) { /* Here arg2 already points to timeSyncHandle because of the registered callBack Yet, explicit usage of timeSyncHandle keeping futuristic approach wherein we might want to add other callbacks and access to handles other than timeSyncHandle */ /*TODO: Review this*/ if(timeSyncHandle->enabled) { TimeSync_Port1linkResetCallBack((uint32_t)linkStatus, (void *)(timeSyncHandle)); } else { DebugP_log("TimeSyncHandle not enabled.Port1 link call back execution failed"); } } void hsrPrp_Port2linkResetCallBack(void *icssEmacHandle, void *linkStatus, void *userArg) { /* Here arg2 already points to timeSyncHandle because of the registered callBack Yet, explicit usage of timeSyncHandle keeping futuristic approach wherein we might want to add other callbacks and access to handles other than timeSyncHandle */ /*TODO: Review this*/ if(timeSyncHandle->enabled) { TimeSync_Port2linkResetCallBack((uint32_t)linkStatus, (void *)(timeSyncHandle)); } else { DebugP_log("TimeSyncHandle not enabled.Port2 link call back execution failed"); } } int32_t app_getEmacHandle(Lwip2Emac_Handle hLwip2Emac) { int32_t ret_val = SystemP_FAILURE; if(hLwip2Emac != NULL) { hLwip2Emac->emacHandle = emachandle; ret_val = SystemP_SUCCESS; } return (ret_val); } void hsrprp_LwipInitStack() { err_t err; sys_sem_t init_sem; /* initialize lwIP stack, network interfaces and applications */ err = sys_sem_new(&init_sem, 0); LWIP_ASSERT("failed to create init_sem", err == ERR_OK); LWIP_UNUSED_ARG(err); tcpip_init(hsrprp_LwipTest_init, &init_sem); /* we have to wait for initialization to finish before calling update_adapter() */ sys_sem_wait(&init_sem); sys_sem_free(&init_sem); } static void hsrprp_LwipTest_init(void * arg) { sys_sem_t *init_sem; LWIP_ASSERT("arg != NULL", arg != NULL); init_sem = (sys_sem_t*)arg; /* init randomizer again (seed per thread) */ srand((unsigned int)sys_now()/1000); /* init network interfaces */ hsrprp_LwipTest_netif_init(); /* init apps */ // hsrprp_LwipApps_init(); //Mosal sys_sem_signal(init_sem); } /* This function initializes all network interfaces */ static void hsrprp_LwipTest_netif_init(void) { /*Variables to store ipAddress, Netmask & Gateway*/ ip4_addr_t ipaddr, netmask, gw; /*Initialise network parameters to zero*/ ip4_addr_set_zero(&gw); ip4_addr_set_zero(&ipaddr); ip4_addr_set_zero(&netmask); LWIP_PORT_INIT_GW(&gw); LWIP_PORT_INIT_IPADDR(&ipaddr); LWIP_PORT_INIT_NETMASK(&netmask); /* Mosal- N0t reading IP address from eeprom because we have to set it manually once. Hence setting static IP */ /*Assign the IP read from EEPROM*/ /* EEPROM_read(gEepromHandle[CONFIG_EEPROM0], SPI_EEPROM_DEVICEIP_OFFSET, (uint8_t *)&ipAddress, 4); changeIPEndianness(&ipAddress);*/ /*Converting Ip from EEPROM to ASCII format & assign to network parametr ipaddr*/ /*if(ip4addr_aton(ip4addr_ntoa((ip4_addr_t *)&ipAddress), &ipaddr) && isValidIP(ip4addr_ntoa((ip4_addr_t *)&ipAddress)))*/ if(isValidIP(ip4addr_ntoa((ip4_addr_t *)&ipAddress))) { DebugP_log("Starting lwIP, local interface static IP is %s\r\n", ip4addr_ntoa(&ipaddr)); } else { /*Initialise default IP address : Can be changed in cfg file */ LWIP_PORT_INIT_IPADDR(&ipaddr); // DebugP_log("Starting lwIP, local interface IP is %s\r\n", ip4addr_ntoa(&ipaddr)); } /*Initialise default gateway address : Can be changed in cfg file*/ LWIP_PORT_INIT_GW(&gw); /*Initialise default Subnet mask : Can be changed in cfg file*/ LWIP_PORT_INIT_NETMASK(&netmask); /*Initialise ICSS EMAC based netif as default netif with above parameters*/ init_default_netif(&ipaddr, &netmask, &gw); /*Inform application about netif status*/ netif_set_status_callback(netif_default, hsrprp_LwipStatus_callback); /*Inform application about link status*/ netif_set_link_callback(netif_default, hsrprp_LwipLink_callback); netif_default->eth_pkt_input = SO_API_EthPktReceive; netif_default->flags |= NETIF_FLAG_BROADCAST; #if USE_DHCP err_t err; autoip_set_struct(netif_default, &netif_autoip); dhcp_set_struct(netif_default, &netif_dhcp); #endif netif_set_up(netif_default); #if USE_DHCP err = dhcp_start(netif_default); LWIP_ASSERT("dhcp_start failed", err == ERR_OK); #elif USE_AUTOIP err = autoip_start(netif_default); LWIP_ASSERT("autoip_start failed", err == ERR_OK); #endif } static void hsrprp_LwipStatus_callback(struct netif *state_netif) { if (netif_is_up(state_netif)) { #if LWIP_IPV4 // DebugP_log("status_callback==UP, local interface IP is %s\r\n", ip4addr_ntoa(netif_ip4_addr(state_netif))); #endif } else { DebugP_log("status_callback==DOWN\r\n"); } } static void hsrprp_LwipLink_callback(struct netif *state_netif) { if (netif_is_link_up(state_netif)) { DebugP_log("link_callback==UP\r\n"); } else { DebugP_log("link_callback==DOWN\r\n"); } } #ifdef MOSAL_REQUIRED void print_cpu_load() { uint32_t cpu_load = TaskP_loadGetTotalCpuLoad(); DebugP_log("CPU load = %3d.%2d %%\r\n", cpu_load/100, cpu_load%100); TaskP_loadResetAll(); } #endif static int32_t hsrprp_LoadFirmware() { uint8_t firmware_Load = SystemP_SUCCESS; /*Initialize the PCP 2 Q map*/ hsrprp_initializePCPtoQueueMap(emachandle); return firmware_Load; }
Hi Jean,
I have gone through the ticket.
Could you please follow the handle initialization sequence mentioned in this file and let us know if this works for you.
/cfs-file/__key/communityserver-discussions-components-files/908/hsr_5F00_prp_5F00_main.c.txt
Hi Nilabh,
Thanks a lot for your response.
Unfortunately we have already received this file, and try to follow the handle initialization (Please made a comparaison with my “hsr_prp_main.c” to see if you find something wrong).
Thanks
Jean-Yves
Due to some internal commitment we could not get back on this, allow us some time to look through the issue, and get back by friday.
We have an update here, we realised the DLR interrupt from the firmware is not coming to R5F due to missing configuration, we are working on resolving the issue, will share the project with you once we are able to fix the issue(tentative by 15th dec)
We have shared the modifed Project with Daviel. He will be sharing it with you soon.
Hello Nilabh,
I have integrated your changes and now it's works fine :-)
DLR is started well and the DLR Object is populated correctly.
Thank you for your support.
Jean-Yves