Tool/software:
I'm trying to make the 'ethercat_slave_beckhoff_ssc_demo' work (Industrial sdk v11.00.00), with a custom board where the ethercat phy is connected to PRU_ICSS0 instead of PRU_ICSS1 as in the example.
I modified tiescsoc.c to use a different PRU_ICSS:
===================================================================
--- tiescsoc.c (revision 44)
+++ tiescsoc.c (working copy)
@@ -43,6 +43,7 @@
#include <kernel/dpl/DebugP.h>
#include "ti_board_open_close.h"
#include "ti_drivers_config.h"
+#undef ICSSG0_INSTANCE
#include <industrial_comms/ethercat_slave/beckhoff_stack/stack_hal/tieschw.h>
#include "tiesc_eeprom.h" /* header equivalent of ESI bin file */
#ifdef MDIO_MANUAL_MODE_ENABLED
@@ -197,8 +198,8 @@
const PRUICSS_HwAttrs *pruicssHwAttrs;
uint32_t inEventLatch0, inEventLatch1, outEventLatch0, outEventLatch1;
- pruIcss1Handle = PRUICSS_open(CONFIG_PRU_ICSS1);
- pruicssHwAttrs = PRUICSS_getAttrs(CONFIG_PRU_ICSS1);
+ pruIcss1Handle = PRUICSS_open(CONFIG_PRU_ICSS0);
+ pruicssHwAttrs = PRUICSS_getAttrs(CONFIG_PRU_ICSS0);
/* Selecting MII-RT mode in GPCFG mux */
PRUICSS_setGpMuxSelect(pruIcss1Handle, PRUICSS_PRU0, PRUICSS_GP_MUX_SEL_MODE_MII);
void tiesc_getFoeFlashOffset(uint32_t *offset)
@@ -315,7 +316,7 @@
int32_t tiesc_getArmInterruptOffset()
{
- PRUICSS_HwAttrs const *pruicssHwAttrs = PRUICSS_getAttrs(CONFIG_PRU_ICSS1);
+ PRUICSS_HwAttrs const *pruicssHwAttrs = PRUICSS_getAttrs(CONFIG_PRU_ICSS0);
int32_t interruptOffset = 0;
So far, I've been able to initialize the slave with a master, I can read the slave XML info and change state. But if I read/write PDO, the functions APPL_OutputMapping and APPL_InputMapping are not called accordingly. Tracing back, it looks like PDITask is stuck waiting for an event:
void PDItask(void *arg)
{
// TaskP_sleep(10 * OS_TICKS_IN_MILLI_SEC);
/*TODO: Check if following is correct*/
ClockP_usleep(10 * 1000);
#if AL_EVENT_ENABLED
uint32_t evtOutNum = HOST_AL_EVENT - 20;
while(1)
{
PRUICSS_waitEvent((PRUICSS_Handle)arg, evtOutNum);
/* ISR processing */
HW_EcatIsr();
}
#endif //AL_EVENT_ENABLED
}
Using the memory browser (via debug probe) I see that the PDO data from the master is written in the corresponding registers (0x30017000 for RxPDO entry 0x7000). I also note that PDO_InputMapping is called from the application main loop. Because of this, I can also verify that the TxPDO is transferred correctly to the master.
void MainLoop(void)
{
/*return if initialization not finished */
if(bInitFinished == FALSE)
{
return;
}
/* FreeRun-Mode: bEscIntEnabled = FALSE, bDcSyncActive = FALSE
Synchron-Mode: bEscIntEnabled = TRUE, bDcSyncActive = FALSE
DC-Mode: bEscIntEnabled = TRUE, bDcSyncActive = TRUE */
if (
(!bEscIntEnabled || !bEcatFirstOutputsReceived) /* SM-Synchronous, but not SM-event received */
&& !bDcSyncActive /* DC-Synchronous */
)
{
/* if the application is running in ECAT Synchron Mode the function ECAT_Application is called
from the ESC interrupt routine,
in ECAT Synchron Mode it should be additionally checked, if the SM-event is received
at least once (bEcatFirstOutputsReceived = 1), otherwise no interrupt is generated
and the function ECAT_Application has to be called here (with interrupts disabled,
because the SM-event could be generated while executing ECAT_Application) */
if ( !bEscIntEnabled )
{
/* application is running in ECAT FreeRun Mode,
first we have to check, if outputs were received */
UINT16 ALEvent = HW_GetALEventRegister();
ALEvent = SWAPWORD(ALEvent);
if ( ALEvent & PROCESS_OUTPUT_EVENT )
{
/* set the flag for the state machine behavior */
bEcatFirstOutputsReceived = TRUE;
if ( bEcatOutputUpdateRunning )
{
/* update the outputs */
PDO_OutputMapping();
}
}
else if ( nPdOutputSize == 0 )
{
/* if no outputs are transmitted, the watchdog must be reset, when the inputs were read */
if ( ALEvent & PROCESS_INPUT_EVENT )
{
/* Outputs were updated, set flag for watchdog monitoring */
bEcatFirstOutputsReceived = TRUE;
}
}
}
DISABLE_ESC_INT();
ECAT_Application();
/*ECATCHANGE_START(V5.13) ECAT 5*/
if ( (bEcatInputUpdateRunning == TRUE) && (nPdInputSize > 0))
/*ECATCHANGE_END(V5.13) ECAT 5*/
{
/* EtherCAT slave is at least in SAFE-OPERATIONAL, update inputs */
PDO_InputMapping();
}
ENABLE_ESC_INT();
}
So, to sum up, I'm able to verify:
- Physical link is established OK
- Master can initialize and get slave info. It can also set it's state
- PDO data is exchanged between master and ESC
What further steps can I take to troubleshoot this? Why is the PDI task hang in PRUICSS_waitEvent?
I've seen a previous thread with a similar issue, but the solution was not published: e2e.ti.com/.../tmds64evm-ethercat-pdo-communication-does-not-work-rx-txpdo-addresses-are-changed