Tool/software:
Hi,
I am trying to get CAN over EtherCAT to work on the AM6442-EVM dev kit using the industrial SDK 09.00.00.03 in combination with the SOES EtherCAT stack. The integration with the BSP-code from TI is taken from the am335 example. So far, the stack gets into OP-mode. Issues start when PDO-communication is expected by the master.
The first issue I have is in making SOES register that there is PDO communication. The ALEvent register state is not properly detected by SOES. Though logging does show that the ALEVENTMASK is set correctly. In this snippet:
/** ESC interrupt enable function by the Slave stack in IRQ mode. * * @param[in] mask = of interrupts to enable */ void ESC_interrupt_enable(uint32_t mask) { DebugP_log("Enabling interrupts: '%X'\r\n", mask); print_present_mask_bits(mask); const uint32_t readmask = bsp_read_dword_isr(escHwPruIcssHandle, ESCREG_ALEVENTMASK); DebugP_log("Already present interrupts are: '%X'\r\n", readmask); print_present_mask_bits(readmask); bsp_write_dword(escHwPruIcssHandle, (mask | readmask), ESCREG_ALEVENTMASK); }
The following is logged:
Enabling interrupts: '400' Bit 'ALEVENT_SM2' is present. Already present interrupts are: 'FFF32B' Bit 'ALEVENT_CONTROL' is present. Bit 'ALEVENT_DC_LATCH' is present. Bit 'ALEVENT_DC_SYNC1' is present. Bit 'ALEVENT_EEP' is present. Bit 'ALEVENT_SM0' is present. Bit 'ALEVENT_SM1' is present.
As the device switches from preOP to safeOP.
If I understand correctly, enabling the interrupt through "bsp_write_dword" in the first snippet should trigger wake-ups on the PRUICSS_waitEvent(pruIcss1Handle, HOST_AL_EVENT - 20) call. That in turn should call PDI_Isr() in SOES that should update ALEvent as shown in this snippet:
/** PDI ISR handler * * @param[in] arg = NOT USED */ void PDI_Isr(void) { uint16_t alevent; alevent = bsp_read_word_isr(escHwPruIcssHandle, ESCREG_ALEVENT); CC_ATOMIC_SET(ESCvar.ALevent, etohs(alevent)); if (ESCvar.ALevent & (ESCREG_ALEVENT_SM2 | ESCREG_ALEVENT_SM3)) { DIG_process(DIG_PROCESS_OUTPUTS_FLAG | DIG_PROCESS_APP_HOOK_FLAG | DIG_PROCESS_INPUTS_FLAG); } }
The problem here is that the value of ALevent never has the 'ESCREG_ALEVENT_SM2'-bit set. Which if I understand correctly is the event for received PDO communication from the master...? Not getting this event means that the slave is not updated with PDO information from the master. This causes for example motor status word to remain 'not operational' because the master cannot change the motor to a more operational state through the slave's RXPDO's.
As a work-around forcing SM2 events is tried. To see if the remainder of the communication control flow does work. This is where another issue was found with PDO communication, where the base address of the process-data-buffer is shifted in the following snippet:
static void ESC_readRXPDO(uint8_t *pData, uint16_t Address, uint16_t Len) { int16_t sm_index; uint16_t ActAddress = bsp_get_process_data_address(escHwPruIcssHandle, Address, Len, &sm_index); // Correct the actualAddr. As it induces an offset. // ActAddress = Address; if (ActAddress < ESC_ADDR_MEMORY) { pd_read_addr_err++; return; } bsp_read(escHwPruIcssHandle, pData, ActAddress, Len); bsp_process_data_access_complete(escHwPruIcssHandle, Address, Len, sm_index); }
Without the reverting of 'ActAddress'. The buffer start address is shifted from its ESI defined location:
0x1800 -> 0x1809
I don't understand why this happens. It also causes data to not be read when SOES begins refreshing the RXPDO here:
/** Read Sync Manager 2 to local process data, Master Outputs. */ void RXPDO_update (void) { if(ESCvar.rxpdo_override != NULL) { (ESCvar.rxpdo_override)(); } else { ESC_read (ESC_SM2_sma, rxpdo, ESCvar.ESC_SM2_sml); if (MAX_MAPPINGS_SM2 > 0) { COE_pdoUnpack (rxpdo, ESCvar.sm2mappings, SMmap2); } } }
Without the reverting of the address in the 'ESC_readRXPDO'-snippet the 'rxpdo'-array given in the above snippet remains empty. While, if the address returned by "bsp_get_process_data_address" is reverted to the ESI address, the buffer does contain the right data, which is passed to our object dictionary, which updates the motor's control word, and passes it into operational mode.
My question is, what is going wrong here that causes SyncManager events to not come through; and RXPDO communication to fail? And where can I read more on this process of sync-manager configuration to get this PDO communication right? I did check the ETG specifications but could not find references to how this buffer configuration should work / be arranged.
Kind regards,
Matthijs