From 48c80f5cae3fc59414e896d89127304ca084a4f1 Mon Sep 17 00:00:00 2001 From: andreas karlsson Date: Sun, 19 Jun 2022 10:51:51 +0200 Subject: [PATCH 1/2] Impove SM validation for input- ouput only slaves Re-add always verify SM length Add validation of SM disabled, don't allow master to activate or set a length if disabled. Add validation of SM enabled, don't allow master to set a length and de-activate. --- soes/esc.c | 49 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 8 deletions(-) diff --git a/soes/esc.c b/soes/esc.c index 07c9a04..706edd6 100644 --- a/soes/esc.c +++ b/soes/esc.c @@ -697,15 +697,32 @@ uint8_t ESC_checkSM23 (uint8_t state) /* fail state change */ return (ESCpreop | ESCerror); } - /* If length > 0 check run-time settings */ - else if ((ESCvar.ESC_SM2_sml > 0) && - ((etohs (SM->Length) != ESCvar.ESC_SM2_sml) || - !(SM->ActESC & ESC_SM2_act))) + /* Check run-time settings */ + /* Check length */ + else if (etohs (SM->Length) != ESCvar.ESC_SM2_sml) { ESCvar.SMtestresult = SMRESULT_ERRSM2; /* fail state change */ return (ESCpreop | ESCerror); } + /* SM disabled and (SM activated or length > 0) set by master */ + else if (((ESC_SM2_act & ESCREG_SYNC_ACT_ACTIVATED) == 0) && + ((SM->ActESC & ESCREG_SYNC_ACT_ACTIVATED) || (etohs (SM->Length) > 0))) + { + ESCvar.SMtestresult = SMRESULT_ERRSM2; + /* fail state change */ + return (ESCpreop | ESCerror); + } + /* SM enabled and (length > 0 but SM disabled) set by master */ + else if (((ESC_SM2_act & ESCREG_SYNC_ACT_ACTIVATED) > 0) && + ((SM->ActESC & ESCREG_SYNC_ACT_ACTIVATED) == 0) && + (etohs (SM->Length) > 0)) + { + ESCvar.SMtestresult = SMRESULT_ERRSM2; + /* fail state change */ + return (ESCpreop | ESCerror); + } + if ((ESC_SM2_sma + (etohs (SM->Length) * 3)) > ESC_SM3_sma) { ESCvar.SMtestresult = SMRESULT_ERRSM2; @@ -723,10 +740,26 @@ uint8_t ESC_checkSM23 (uint8_t state) /* fail state change */ return (ESCpreop | ESCerror); } - /* If length > 0 check run-time settings */ - else if ((ESCvar.ESC_SM3_sml > 0) && - ((etohs (SM->Length) != ESCvar.ESC_SM3_sml) || - !(SM->ActESC & ESC_SM3_act))) + /* Check run-time settings */ + /* Check length */ + else if (etohs (SM->Length) != ESCvar.ESC_SM3_sml) + { + ESCvar.SMtestresult = SMRESULT_ERRSM3; + /* fail state change */ + return (ESCpreop | ESCerror); + } + /* SM disabled and (SM activated or length > 0) set by master */ + else if (((ESC_SM3_act & ESCREG_SYNC_ACT_ACTIVATED) == 0) && + ((SM->ActESC & ESCREG_SYNC_ACT_ACTIVATED) || (etohs (SM->Length) > 0))) + { + ESCvar.SMtestresult = SMRESULT_ERRSM3; + /* fail state change */ + return (ESCpreop | ESCerror); + } + /* SM enabled and (length > 0 but SM disabled) set by master */ + else if (((ESC_SM3_act & ESCREG_SYNC_ACT_ACTIVATED) > 0) && + ((SM->ActESC & ESCREG_SYNC_ACT_ACTIVATED) == 0) && + (etohs (SM->Length) > 0)) { ESCvar.SMtestresult = SMRESULT_ERRSM3; /* fail state change */ From 8ebb78ea109c7b9ff766bf9e77da6345651aba08 Mon Sep 17 00:00:00 2001 From: Andreas Karlsson Date: Sat, 2 Jul 2022 10:16:21 +0200 Subject: [PATCH 2/2] Enable SM3 interrupt for input only slave Enable SM3 interrupt if the slave only got inputs. On PREOP_TO_SAFEOP do an intial write to SM3, otherwise the SM3 will never occur since there is no data present to read. --- applications/rtl_xmc4_dynpdo/main.c | 8 ++++++++ soes/esc.c | 26 +++++++++++++++--------- soes/hal/raspberrypi-lan9252/esc_hw.c | 29 +++++++++++++-------------- soes/hal/rt-kernel-xmc4/esc_hw.c | 4 ++-- soes/hal/tiesc/esc_hw.c | 2 +- 5 files changed, 42 insertions(+), 27 deletions(-) diff --git a/applications/rtl_xmc4_dynpdo/main.c b/applications/rtl_xmc4_dynpdo/main.c index 9a2ffa9..e6f37f2 100644 --- a/applications/rtl_xmc4_dynpdo/main.c +++ b/applications/rtl_xmc4_dynpdo/main.c @@ -38,6 +38,13 @@ void cb_state_change (uint8_t * as, uint8_t * an) /* Enable watchdog interrupt */ ESC_ALeventmaskwrite (ESC_ALeventmaskread() | ESCREG_ALEVENT_WD); } + else if (*as == PREOP_TO_SAFEOP) + { + /* Write initial input data requried if an input only slave, + * otherwise the SM3 will never occur. + */ + DIG_process (DIG_PROCESS_INPUTS_FLAG); + } } /* Setup of DC */ @@ -70,6 +77,7 @@ int main (void) .esc_hw_interrupt_disable = ESC_interrupt_disable, .esc_hw_eep_handler = ESC_eep_handler, .esc_check_dc_handler = dc_checker + .get_device_id = NULL }; rprintf ("Hello world\n"); diff --git a/soes/esc.c b/soes/esc.c index 706edd6..7efadcc 100644 --- a/soes/esc.c +++ b/soes/esc.c @@ -707,7 +707,7 @@ uint8_t ESC_checkSM23 (uint8_t state) } /* SM disabled and (SM activated or length > 0) set by master */ else if (((ESC_SM2_act & ESCREG_SYNC_ACT_ACTIVATED) == 0) && - ((SM->ActESC & ESCREG_SYNC_ACT_ACTIVATED) || (etohs (SM->Length) > 0))) + ((SM->ActESC & ESCREG_SYNC_ACT_ACTIVATED) || (ESCvar.ESC_SM2_sml > 0))) { ESCvar.SMtestresult = SMRESULT_ERRSM2; /* fail state change */ @@ -716,7 +716,7 @@ uint8_t ESC_checkSM23 (uint8_t state) /* SM enabled and (length > 0 but SM disabled) set by master */ else if (((ESC_SM2_act & ESCREG_SYNC_ACT_ACTIVATED) > 0) && ((SM->ActESC & ESCREG_SYNC_ACT_ACTIVATED) == 0) && - (etohs (SM->Length) > 0)) + (ESCvar.ESC_SM2_sml > 0)) { ESCvar.SMtestresult = SMRESULT_ERRSM2; /* fail state change */ @@ -750,7 +750,7 @@ uint8_t ESC_checkSM23 (uint8_t state) } /* SM disabled and (SM activated or length > 0) set by master */ else if (((ESC_SM3_act & ESCREG_SYNC_ACT_ACTIVATED) == 0) && - ((SM->ActESC & ESCREG_SYNC_ACT_ACTIVATED) || (etohs (SM->Length) > 0))) + ((SM->ActESC & ESCREG_SYNC_ACT_ACTIVATED) || (ESCvar.ESC_SM3_sml > 0))) { ESCvar.SMtestresult = SMRESULT_ERRSM3; /* fail state change */ @@ -759,7 +759,7 @@ uint8_t ESC_checkSM23 (uint8_t state) /* SM enabled and (length > 0 but SM disabled) set by master */ else if (((ESC_SM3_act & ESCREG_SYNC_ACT_ACTIVATED) > 0) && ((SM->ActESC & ESCREG_SYNC_ACT_ACTIVATED) == 0) && - (etohs (SM->Length) > 0)) + (ESCvar.ESC_SM3_sml > 0)) { ESCvar.SMtestresult = SMRESULT_ERRSM3; /* fail state change */ @@ -827,15 +827,22 @@ uint8_t ESC_startinput (uint8_t state) { if (ESCvar.esc_hw_interrupt_enable != NULL) { - if(ESCvar.dcsync > 0) + uint32_t int_mask; + + if (ESCvar.ESC_SM2_sml == 0) { - ESCvar.esc_hw_interrupt_enable(ESCREG_ALEVENT_DC_SYNC0 | - ESCREG_ALEVENT_SM2); + int_mask = ESCREG_ALEVENT_SM3; } else { - ESCvar.esc_hw_interrupt_enable(ESCREG_ALEVENT_SM2); + int_mask = ESCREG_ALEVENT_SM2; } + + if (ESCvar.dcsync > 0) + { + int_mask |= ESCREG_ALEVENT_DC_SYNC0; + } + ESCvar.esc_hw_interrupt_enable (int_mask); } } } @@ -858,7 +865,8 @@ void ESC_stopinput (void) (ESCvar.esc_hw_interrupt_disable != NULL)) { ESCvar.esc_hw_interrupt_disable (ESCREG_ALEVENT_DC_SYNC0 | - ESCREG_ALEVENT_SM2); + ESCREG_ALEVENT_SM2 | + ESCREG_ALEVENT_SM3); } } diff --git a/soes/hal/raspberrypi-lan9252/esc_hw.c b/soes/hal/raspberrypi-lan9252/esc_hw.c index a98cfc9..e061550 100644 --- a/soes/hal/raspberrypi-lan9252/esc_hw.c +++ b/soes/hal/raspberrypi-lan9252/esc_hw.c @@ -567,15 +567,13 @@ void ESC_init (const esc_cfg_t * config) void ESC_interrupt_enable (uint32_t mask) { - if (ESCREG_ALEVENT_DC_SYNC0 & mask) + // Enable interrupt for SYNC0 or SM2 or SM3 + uint32_t user_int_mask = ESCREG_ALEVENT_DC_SYNC0 | + ESCREG_ALEVENT_SM2 | + ESCREG_ALEVENT_SM3; + if (mask & user_int_mask) { - // Enable interrupt from SYNC0 - ESC_ALeventmaskwrite(ESC_ALeventmaskread() | ESCREG_ALEVENT_DC_SYNC0); - } - if (ESCREG_ALEVENT_SM2 & mask) - { - // Enable interrupt from SYNC0 - ESC_ALeventmaskwrite(ESC_ALeventmaskread() | ESCREG_ALEVENT_SM2); + ESC_ALeventmaskwrite(ESC_ALeventmaskread() | (mask & user_int_mask)); } // Set LAN9252 interrupt pin driver as push-pull active high @@ -587,17 +585,18 @@ void ESC_interrupt_enable (uint32_t mask) void ESC_interrupt_disable (uint32_t mask) { - if (ESCREG_ALEVENT_DC_SYNC0 & mask) + // Enable interrupt for SYNC0 or SM2 or SM3 + uint32_t user_int_mask = ESCREG_ALEVENT_DC_SYNC0 | + ESCREG_ALEVENT_SM2 | + ESCREG_ALEVENT_SM3; + + if (mask & user_int_mask) { // Disable interrupt from SYNC0 - ESC_ALeventmaskwrite(ESC_ALeventmaskread() & ~(ESCREG_ALEVENT_DC_SYNC0)); - } - if (ESCREG_ALEVENT_SM2 & mask) - { - // Disable interrupt from SM2 - ESC_ALeventmaskwrite(ESC_ALeventmaskread() & ~(ESCREG_ALEVENT_SM2)); + ESC_ALeventmaskwrite(ESC_ALeventmaskread() & ~(mask & user_int_mask)); } + // Disable LAN9252 interrupt bcm2835_spi_write_32(ESC_CMD_INT_EN, 0x00000000); } diff --git a/soes/hal/rt-kernel-xmc4/esc_hw.c b/soes/hal/rt-kernel-xmc4/esc_hw.c index bf36838..9e1b0ac 100644 --- a/soes/hal/rt-kernel-xmc4/esc_hw.c +++ b/soes/hal/rt-kernel-xmc4/esc_hw.c @@ -242,8 +242,8 @@ static void ecat_isr (void * arg) CC_ATOMIC_SET(ESCvar.ALevent, etohl(ecat0->AL_EVENT_REQ)); CC_ATOMIC_SET(ESCvar.Time, etohl(ecat0->READMode_DC_SYS_TIME[0])); - /* Handle SM2 interrupt */ - if(ESCvar.ALevent & ESCREG_ALEVENT_SM2) + /* Handle SM2 & SM3 interrupt */ + if(ESCvar.ALevent & (ESCREG_ALEVENT_SM2 | ESCREG_ALEVENT_SM3)) { /* Is DC active or not */ if(ESCvar.dcsync == 0) diff --git a/soes/hal/tiesc/esc_hw.c b/soes/hal/tiesc/esc_hw.c index c3b0690..931bcdf 100644 --- a/soes/hal/tiesc/esc_hw.c +++ b/soes/hal/tiesc/esc_hw.c @@ -301,7 +301,7 @@ void PDI_Isr(void) alevent = bsp_read_word_isr(escHwPruIcssHandle,ESCREG_ALEVENT); CC_ATOMIC_SET(ESCvar.ALevent, etohs(alevent)); - if(ESCvar.ALevent & ESCREG_ALEVENT_SM2) + if(ESCvar.ALevent & (ESCREG_ALEVENT_SM2 & ESCREG_ALEVENT_SM3)) { DIG_process(DIG_PROCESS_OUTPUTS_FLAG | DIG_PROCESS_APP_HOOK_FLAG |