AnsweredAssumed Answered

fsl_enet for i.MX RT106x not able to handle ENET2

Question asked by Dirk Castelijns on Nov 14, 2019
Latest reply on Nov 17, 2019 by Daniel Chen

The fsl_enet drivers in the SDK for i.MX RT106x contain some array of data structures based on the number of ENET peripherals available. There is a mismatch in number of array elements which causes a HardFault when using ENET2.


Looking at fsl_enet.c, we see several arrays being declared:


/*! @brief Pointers to enet handles for each instance. */
static enet_handle_t *s_ENETHandle[FSL_FEATURE_SOC_ENET_COUNT] = {NULL};

/*! @brief Pointers to enet clocks for each instance. */
const clock_ip_name_t s_enetClock[] = ENET_CLOCKS;


/*! @brief Pointers to enet transmit IRQ number for each instance. */
static const IRQn_Type s_enetTxIrqId[] = ENET_Transmit_IRQS;
/*! @brief Pointers to enet receive IRQ number for each instance. */
static const IRQn_Type s_enetRxIrqId[] = ENET_Receive_IRQS;
/*! @brief Pointers to enet timestamp IRQ number for each instance. */
static const IRQn_Type s_enetTsIrqId[] = ENET_1588_Timer_IRQS;
/*! @brief Pointers to enet error IRQ number for each instance. */
static const IRQn_Type s_enetErrIrqId[] = ENET_Error_IRQS;

/*! @brief Pointers to enet bases for each instance. */
static ENET_Type *const s_enetBases[] = ENET_BASE_PTRS;



The s_ENETHandle[] array size is determined by FSL_FEATURE_SOC_ENET_COUNT defined in MIMXRT1062_features.h:


/* @brief ENET availability on the SoC. */

All the other array sizes are determine by macro's in MIMXRT1062.h:

/** Array initializer of ENET peripheral base addresses */
/** Array initializer of ENET peripheral base pointers */
#define ENET_BASE_PTRS { ENET, (ENET_Type *)0u, ENET2 }
/** Interrupt vectors for the ENET peripheral type */
#define ENET_Transmit_IRQS { ENET_IRQn, NotAvail_IRQn, ENET2_IRQn }
#define ENET_Receive_IRQS { ENET_IRQn, NotAvail_IRQn, ENET2_IRQn }
#define ENET_Error_IRQS { ENET_IRQn, NotAvail_IRQn, ENET2_IRQn }
#define ENET_1588_Timer_IRQS { ENET_1588_Timer_IRQn, NotAvail_IRQn, ENET2_1588_Timer_IRQn }

As you can see the macro expand to 3 elements while s_ENETHandle[] has only 2 elements. For some reason they left a gap between ENET and ENET2.  


At several places in fsl_enet.c the function ENET_GetInstance(base) is used to determine the index for one of the arrays above. Because this function iterates through s_enetBases[], the returned index can be 0 to 2 (because there are three elements).  All arrays can be accesses this way except for s_ENETHandle[] but this is done in several places in fsl_enet.c. For instance in ENET_SetHandler():

static void ENET_SetHandler(ENET_Type *base,
      enet_handle_t *handle,
      const enet_config_t *config,
      const enet_buffer_config_t *bufferConfig)
   uint8_t count;
   uint32_t instance = ENET_GetInstance(base);


   <removed part for clarity


   /* Save the handle pointer in the global variables. */
   s_ENETHandle[instance] = handle;



As you can imagine, things can go horribly wrong this way.


For now we got things working by setting FSL_FEATURE_SOC_ENET_COUNT to 3 but this is strange because the device has only 2 ENET's.