Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MCUXpresso: Fix ENET driver to enable interrupts after interrupt handler is set #3519

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@
#define ENET_NTOHS(n) __REV16(n)
#define ENET_NTOHL(n) __REV(n)

/* Typedef for interrupt handler. */
typedef void (*enet_isr_t)(ENET_Type *base, enet_handle_t *handle);
/*******************************************************************************
* Prototypes
******************************************************************************/
Expand All @@ -132,7 +134,18 @@ static void ENET_SetMacController(ENET_Type *base,
const enet_buffer_config_t *bufferConfig,
uint8_t *macAddr,
uint32_t srcClock_Hz);

/*!
* @brief Set ENET handler.
*
* @param base ENET peripheral base address.
* @param handle The ENET handle pointer.
* @param config ENET configuration stucture pointer.
* @param bufferConfig ENET buffer configuration.
*/
static void ENET_SetHandler(ENET_Type *base,
enet_handle_t *handle,
const enet_config_t *config,
const enet_buffer_config_t *bufferConfig);
/*!
* @brief Set ENET MAC transmit buffer descriptors.
*
Expand Down Expand Up @@ -226,22 +239,26 @@ static status_t ENET_StoreRxFrameTime(ENET_Type *base, enet_handle_t *handle, en
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[FSL_FEATURE_SOC_ENET_COUNT] = ENET_CLOCKS;
const clock_ip_name_t s_enetClock[] = ENET_CLOCKS;

/*! @brief Pointers to enet transmit IRQ number for each instance. */
const IRQn_Type s_enetTxIrqId[] = ENET_Transmit_IRQS;
static const IRQn_Type s_enetTxIrqId[] = ENET_Transmit_IRQS;
/*! @brief Pointers to enet receive IRQ number for each instance. */
const IRQn_Type s_enetRxIrqId[] = ENET_Receive_IRQS;
static const IRQn_Type s_enetRxIrqId[] = ENET_Receive_IRQS;
#if defined(ENET_ENHANCEDBUFFERDESCRIPTOR_MODE) && ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
/*! @brief Pointers to enet timestamp IRQ number for each instance. */
const IRQn_Type s_enetTsIrqId[] = ENET_1588_Timer_IRQS;
static const IRQn_Type s_enetTsIrqId[] = ENET_1588_Timer_IRQS;
#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
/*! @brief Pointers to enet error IRQ number for each instance. */
const IRQn_Type s_enetErrIrqId[] = ENET_Error_IRQS;
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;

/* ENET ISR for transactional APIs. */
static enet_isr_t s_enetTxIsr;
static enet_isr_t s_enetRxIsr;
static enet_isr_t s_enetErrIsr;
/*******************************************************************************
* Code
******************************************************************************/
Expand Down Expand Up @@ -312,26 +329,13 @@ void ENET_Init(ENET_Type *base,
/* Initializes the ENET receive buffer descriptors. */
ENET_SetRxBufferDescriptors(bufferConfig->rxBdStartAddrAlign, bufferConfig->rxBufferAlign,
bufferConfig->rxBuffSizeAlign, bufferConfig->rxBdNumber,
!!(config->interrupt & (kENET_RxFrameInterrupt | kENET_RxByteInterrupt)));
!!(config->interrupt & (kENET_RxFrameInterrupt | kENET_RxBufferInterrupt)));

/* Initializes the ENET MAC controller. */
ENET_SetMacController(base, config, bufferConfig, macAddr, srcClock_Hz);

/* Initialize the handle to zero. */
memset(handle, 0, sizeof(enet_handle_t));

/* Store transfer parameters in handle pointer. */
handle->rxBdBase = bufferConfig->rxBdStartAddrAlign;
handle->rxBdCurrent = bufferConfig->rxBdStartAddrAlign;
handle->rxBdDirty = bufferConfig->rxBdStartAddrAlign;
handle->txBdBase = bufferConfig->txBdStartAddrAlign;
handle->txBdCurrent = bufferConfig->txBdStartAddrAlign;
handle->txBdDirty = bufferConfig->txBdStartAddrAlign;
handle->rxBuffSizeAlign = bufferConfig->rxBuffSizeAlign;
handle->txBuffSizeAlign = bufferConfig->txBuffSizeAlign;

/* Save the handle pointer in the global variables. */
s_ENETHandle[instance] = handle;
/* Set all buffers or data in handler for data transmit/receive process. */
ENET_SetHandler(base, handle, config, bufferConfig);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Step 1. Please move ENET_SetHandler() above ENET_setMacController()

}

void ENET_Deinit(ENET_Type *base)
Expand All @@ -355,6 +359,44 @@ void ENET_SetCallback(enet_handle_t *handle, enet_callback_t callback, void *use
handle->userData = userData;
}

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

memset(handle, 0, sizeof(enet_handle_t));

handle->rxBdBase = bufferConfig->rxBdStartAddrAlign;
handle->rxBdCurrent = bufferConfig->rxBdStartAddrAlign;
handle->txBdBase = bufferConfig->txBdStartAddrAlign;
handle->txBdCurrent = bufferConfig->txBdStartAddrAlign;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

handle->txBdDirty = bufferConfig->txBdStartAddrAlign;
Adding this will fix your PR.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same to the K64F files as well

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for looking into this and finding the issue. I have update the PR.

handle->txBdDirty = bufferConfig->txBdStartAddrAlign;
handle->rxBuffSizeAlign = bufferConfig->rxBuffSizeAlign;
handle->txBuffSizeAlign = bufferConfig->txBuffSizeAlign;

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

/* Set the IRQ handler when the interrupt is enabled. */
if (config->interrupt & ENET_TX_INTERRUPT)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Step 2. Please move this if-else section from here to ENET_SetMacController() , paste it after "ENET_EnableInterrupts(base, config->interrupt)" but before "ecr = base->ECR;"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, you are correct, I have changed txBuffSizeAlign to txBuffStartAlign.

With regards to the remaining, I don't see why those changes are required. The code enables the interrupts in the NVIC inside ENET_SetHandler() which is the done after the handle is saved in the global variable. This should address the issue reported.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR has been updated.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, so you mean that ENET_EnableInterrupts(base, config->interrupt enable interrupts for the enet module and NVIC still at that particular time gates the interrupts to processor ? Alrigh, if that's the case. I think I got your point. I was of the view that when you write to base->EIMR, it enables interrupts globally.

{
s_enetTxIsr = ENET_TransmitIRQHandler;
EnableIRQ(s_enetTxIrqId[instance]);
}
if (config->interrupt & ENET_RX_INTERRUPT)
{
s_enetRxIsr = ENET_ReceiveIRQHandler;
EnableIRQ(s_enetRxIrqId[instance]);
}
if (config->interrupt & ENET_ERR_INTERRUPT)
{
s_enetErrIsr = ENET_ErrorIRQHandler;
EnableIRQ(s_enetErrIrqId[instance]);
}
}

static void ENET_SetMacController(ENET_Type *base,
const enet_config_t *config,
const enet_buffer_config_t *bufferConfig,
Expand Down Expand Up @@ -452,20 +494,6 @@ static void ENET_SetMacController(ENET_Type *base,

/* Enables Ethernet interrupt and NVIC. */
ENET_EnableInterrupts(base, config->interrupt);
if (config->interrupt & (kENET_RxByteInterrupt | kENET_RxFrameInterrupt))
{
EnableIRQ(s_enetRxIrqId[instance]);
}
if (config->interrupt & (kENET_TxByteInterrupt | kENET_TxFrameInterrupt))
{
EnableIRQ(s_enetTxIrqId[instance]);
}
if (config->interrupt & (kENET_BabrInterrupt | kENET_BabtInterrupt | kENET_GraceStopInterrupt | kENET_MiiInterrupt |
kENET_EBusERInterrupt | kENET_LateCollisionInterrupt | kENET_RetryLimitInterrupt |
kENET_UnderrunInterrupt | kENET_PayloadRxInterrupt | kENET_WakeupInterrupt))
{
EnableIRQ(s_enetErrIrqId[instance]);
}

/* ENET control register setting. */
ecr = base->ECR;
Expand All @@ -490,10 +518,10 @@ static void ENET_SetTxBufferDescriptors(volatile enet_tx_bd_struct_t *txBdStartA

for (count = 0; count < txBdNumber; count++)
{
if (txBuffSizeAlign != NULL)
if (txBuffStartAlign != NULL)
{
/* Set data buffer address. */
curBuffDescrip->buffer = (uint8_t *)((uint32_t)&txBuffStartAlign[count * txBuffSizeAlign]);
/* Set data buffer address. */
curBuffDescrip->buffer = (uint8_t *)((uint32_t)&txBuffStartAlign[count * txBuffSizeAlign]);
}
else
{
Expand All @@ -517,6 +545,7 @@ static void ENET_SetTxBufferDescriptors(volatile enet_tx_bd_struct_t *txBdStartA
/* Increase the index. */
curBuffDescrip++;
}

}

static void ENET_SetRxBufferDescriptors(volatile enet_rx_bd_struct_t *rxBdStartAlign,
Expand Down Expand Up @@ -564,12 +593,8 @@ static void ENET_SetRxBufferDescriptors(volatile enet_rx_bd_struct_t *rxBdStartA

void ENET_SetMII(ENET_Type *base, enet_mii_speed_t speed, enet_mii_duplex_t duplex)
{
uint32_t rcr;
uint32_t tcr;

rcr = base->RCR;
tcr = base->TCR;

uint32_t rcr = base->RCR;
uint32_t tcr = base->TCR;
/* Sets speed mode. */
if (kENET_MiiSpeed10M == speed)
{
Expand Down Expand Up @@ -1274,11 +1299,9 @@ void ENET_Ptp1588Configure(ENET_Type *base, enet_handle_t *handle, enet_ptp_conf

/* Enables the time stamp interrupt for the master clock on a device. */
ENET_EnableInterrupts(base, kENET_TsTimerInterrupt);
EnableIRQ(s_enetTsIrqId[instance]);

/* Enables the transmit interrupt to store the transmit frame time-stamp. */
ENET_EnableInterrupts(base, kENET_TxFrameInterrupt);
EnableIRQ(s_enetTxIrqId[instance]);
ENET_DisableInterrupts(base, kENET_TxBufferInterrupt);

/* Setting the receive and transmit state for transaction. */
handle->rxPtpTsDataRing.ptpTsData = ptpConfig->rxPtpTsData;
Expand All @@ -1292,6 +1315,11 @@ void ENET_Ptp1588Configure(ENET_Type *base, enet_handle_t *handle, enet_ptp_conf
handle->msTimerSecond = 0;
handle->txBdDirtyTime = handle->txBdBase;
handle->txBdDirtyStatic = handle->txBdBase;

/* Set the IRQ handler when the interrupt is enabled. */
s_enetTxIsr = ENET_TransmitIRQHandler;
EnableIRQ(s_enetTsIrqId[instance]);
EnableIRQ(s_enetTxIrqId[instance]);
}

void ENET_Ptp1588StartTimer(ENET_Type *base, uint32_t ptpClkSrc)
Expand Down Expand Up @@ -1591,14 +1619,19 @@ void ENET_TransmitIRQHandler(ENET_Type *base, enet_handle_t *handle)
assert(handle);

/* Check if the transmit interrupt happen. */
if ((kENET_TxByteInterrupt | kENET_TxFrameInterrupt) & base->EIR)
while ((kENET_TxBufferInterrupt | kENET_TxFrameInterrupt) & base->EIR)
{
/* Clear the transmit interrupt event. */
base->EIR = kENET_TxFrameInterrupt | kENET_TxByteInterrupt;
#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
if (base->EIR & kENET_TxFrameInterrupt)
{
/* Store the transmit timestamp from the buffer descriptor should be done here. */
ENET_StoreTxFrameTime(base, handle);
}
#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */

/* Clear the transmit interrupt event. */
base->EIR = kENET_TxFrameInterrupt | kENET_TxBufferInterrupt;

/* Callback function. */
if (handle->callback)
{
Expand All @@ -1612,10 +1645,10 @@ void ENET_ReceiveIRQHandler(ENET_Type *base, enet_handle_t *handle)
assert(handle);

/* Check if the receive interrupt happen. */
if ((kENET_RxByteInterrupt | kENET_RxFrameInterrupt) & base->EIR)
while ((kENET_RxBufferInterrupt | kENET_RxFrameInterrupt) & base->EIR)
{
/* Clear the transmit interrupt event. */
base->EIR = kENET_RxFrameInterrupt | kENET_RxByteInterrupt;
base->EIR = kENET_RxFrameInterrupt | kENET_RxBufferInterrupt;

/* Callback function. */
if (handle->callback)
Expand Down Expand Up @@ -1688,26 +1721,24 @@ void ENET_Ptp1588TimerIRQHandler(ENET_Type *base, enet_handle_t *handle)
}
}
}

void ENET_1588_Timer_IRQHandler(void)
{
ENET_Ptp1588TimerIRQHandler(ENET, s_ENETHandle[0]);
}
#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */

void ENET_Transmit_IRQHandler(void)
{
ENET_TransmitIRQHandler(ENET, s_ENETHandle[0]);
s_enetTxIsr(ENET, s_ENETHandle[0]);
}

void ENET_Receive_IRQHandler(void)
{
ENET_ReceiveIRQHandler(ENET, s_ENETHandle[0]);
s_enetRxIsr(ENET, s_ENETHandle[0]);
}

void ENET_Error_IRQHandler(void)
{
ENET_ErrorIRQHandler(ENET, s_ENETHandle[0]);
}

void ENET_1588_Timer_IRQHandler(void)
{
#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
ENET_Ptp1588TimerIRQHandler(ENET, s_ENETHandle[0]);
#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
s_enetErrIsr(ENET, s_ENETHandle[0]);
}
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,10 @@
#define ENET_BUFFDESCRIPTOR_RX_EXT_ERR_MASK \
(ENET_BUFFDESCRIPTOR_RX_MACERR_MASK | ENET_BUFFDESCRIPTOR_RX_PHYERR_MASK | ENET_BUFFDESCRIPTOR_RX_COLLISION_MASK)
#endif
#define ENET_TX_INTERRUPT (kENET_TxFrameInterrupt | kENET_TxBufferInterrupt)
#define ENET_RX_INTERRUPT (kENET_RxFrameInterrupt | kENET_RxBufferInterrupt)
#define ENET_ERR_INTERRUPT (kENET_BabrInterrupt | kENET_BabtInterrupt | kENET_EBusERInterrupt | \
kENET_LateCollisionInterrupt | kENET_RetryLimitInterrupt | kENET_UnderrunInterrupt | kENET_PayloadRxInterrupt)

/*! @name Defines the maximum Ethernet frame size. */
/*@{*/
Expand Down Expand Up @@ -224,9 +228,9 @@ typedef enum _enet_interrupt_enable
kENET_BabtInterrupt = ENET_EIR_BABT_MASK, /*!< Babbling transmit error interrupt source */
kENET_GraceStopInterrupt = ENET_EIR_GRA_MASK, /*!< Graceful stop complete interrupt source */
kENET_TxFrameInterrupt = ENET_EIR_TXF_MASK, /*!< TX FRAME interrupt source */
kENET_TxByteInterrupt = ENET_EIR_TXB_MASK, /*!< TX BYTE interrupt source */
kENET_TxBufferInterrupt = ENET_EIR_TXB_MASK, /*!< TX BUFFER interrupt source */
kENET_RxFrameInterrupt = ENET_EIR_RXF_MASK, /*!< RX FRAME interrupt source */
kENET_RxByteInterrupt = ENET_EIR_RXB_MASK, /*!< RX BYTE interrupt source */
kENET_RxBufferInterrupt = ENET_EIR_RXB_MASK, /*!< RX BUFFER interrupt source */
kENET_MiiInterrupt = ENET_EIR_MII_MASK, /*!< MII interrupt source */
kENET_EBusERInterrupt = ENET_EIR_EBERR_MASK, /*!< Ethernet bus error interrupt source */
kENET_LateCollisionInterrupt = ENET_EIR_LC_MASK, /*!< Late collision interrupt source */
Expand Down
Loading