Hello
I am using the lwIP protocol with the EMAC module for data transmission and reception. Sending data works perfectly fine, but I'm facing an issue with the EMAC module when it comes to receiving data. After receiving data for a certain period of time, the EMAC module fails to enter the receive interrupt. I'm seeking assistance on how to resolve this problem and ensure that the EMAC module can consistently receive data without interruptions. Thank you!
My lwIP initialization is as follows:
void EMAC_LwIP_init (uint8_t * macAddress)
{
unsigned int ipAddr;
uint32 emacCtrlBase = 0xFCF78800U;
uint32 emacBase = 0xFCF78000U;
EMACInit(emacCtrlBase,emacBase);
IntMasterIRQEnable();//中断
/* for static IP address. Change address as required, and uncomment the previous statement. */
uint8 ip_addr[4] = { 172, 22, 1, 1 };
uint8 netmask[4] = { 255, 255, 255, 0 };
uint8 gateway[4] = { 172, 22, 1, 1 };
ipAddr = lwIPInit(0, macAddress,
*((uint32_t *)ip_addr),
*((uint32_t *)netmask),
*((uint32_t *)gateway),
IPADDR_USE_STATIC );
}
And my EMAC module's receive interrupt is as shown below. During testing, I noticed that the receive interrupt stops occurring after the R0 (Receive Idle Buffer Count Register) receives the value 0xCD(After this point, the register does not change unless I reinitialize). I suspect there might be an issue with the tail processing in my interrupt function. Here's my interrupt function:
#pragma INTERRUPT(EMACCore0RxIsr, IRQ)
uint32 countrxisr = 0;
void EMACCore0RxIsr(void)
{
char* tmpptr;
uint32_t tmp = 0;
uint32_t CurFinishCP = HWREG(EMAC_BASE + EMAC_RXCP(0)); /* Pointer to the buffer that has completed data reception */
EMACDesc_t* RXCP = EMAC_SL_CurRXCP; /* Pointer to the current processing receive buffer */
MACFrame_t* MacFramePtr = NULL;
ECTRL_C0RXEN = 0U; /* Disable interrupts before processing data */
HWREG(EMAC_BASE + EMAC_RXCP(0)) = CurFinishCP; /* Confirm the current processed CP (Complete Pointer) */
HWREG(EMAC_BASE + EMAC_MACEOIVECTOR) = 1U; /* Acknowledge the completion of receive interrupt */
if (countrxisr == 0U) // First frame
{
HWREG(EMAC_BASE + EMAC_RXHDP(0)) = CurFinishCP;
EMAC_SL_CurRXCP = (EMACDesc_t*)CurFinishCP;
RXCP = (EMACDesc_t*)CurFinishCP;
countrxisr = 1;
} /* When the current receive queue reaches the end, reassign the receive buffer pointer to the first position */
else if (HWREG(EMAC_BASE + EMAC_RXHDP(0)) == 0U)
{
HWREG(EMAC_BASE + EMAC_RXHDP(0)) = CurFinishCP;
EMAC_SL_CurRXCP = (EMACDesc_t*)CurFinishCP;
RXCP = (EMACDesc_t*)CurFinishCP; // Original
} /* When the current receive queue reaches the end, reassign the receive buffer pointer to the first position */
else
{
EMAC_SL_CurRXCP = ((EMACDesc_t*)(CurFinishCP)) + 1U;
EMAC_SL_CurRXCP = (EMACDesc_t*)((char*)EMAC_SL_CurRXCP + 4); /* Appear 4 bytes more data than 3137, so add this offset */
} /* Update the last processed CP */
while ((uint32_t)(RXCP) <= CurFinishCP)
{
/*1============================================================================1*/
/* Only process single packet data, discard fragmented data packets */
if ((RXCP->EOP == 1U) && (RXCP->SOP == 1U))
{
MacFramePtr = (MACFrame_t*)EMACSwizzleData((uint32)RXCP->BufferPtr); /* Pointer to MAC layer data frame information */
switch (MacFramePtr->FrameType)
{
case IPV4_DT_ARP_FRAME:
{
if (EMACSwizzleData16(RXCP->Length) <= sizeof EMAC_SL_RXBuffer.Data[0].Buffer)
{
memcpy(EMAC_SL_RXBuffer.Data[EMAC_SL_RXBuffer.Tail.Cnt].Buffer, EMACSwizzleData(RXCP->BufferPtr), EMACSwizzleData16(RXCP->Length));
EMAC_SL_RXBuffer.Tail.Cnt++;
}
break;
} /* Received ARP data frame, store the data in the receive buffer for later processing */
case IPV4_DT_IP_FRAME:
{
IPHeader_t* IPHeaderPtr = (IPHeader_t*)(EMACSwizzleData(RXCP->BufferPtr) + 14U); /* IP header information of the current data packet */
if ((IPHeaderPtr->SrcIP == REMOTE_IP_ADDR) && ((IPHeaderPtr->DstIP == LOCAL_IP_ADDR) || (IPHeaderPtr->DstIP == BROADCAST_IP_ADDR)) && (IPHeaderPtr->Protol == IP_PROTO_UDP))
{
EMAC_SL_IsRXRemoteUDPData = TRUE;
if (EMACSwizzleData16(RXCP->Length) <= sizeof EMAC_SL_RXBuffer.Data[0].Buffer)
{
memcpy(EMAC_SL_RXBuffer.Data[EMAC_SL_RXBuffer.Tail.Cnt].Buffer, EMACSwizzleData(RXCP->BufferPtr), EMACSwizzleData16(RXCP->Length));
EMAC_SL_RXBuffer.Tail.Cnt++;
}
} /* Received IP address matches the local IP address and data type is UDP, then process the data frame */
break;
} /* Received IP data frame, store the data in the receive buffer for later processing */
default:
{
break;
}
}
}
/*1============================================================================1*/
RXCP->Length = RX_BUFFER_SIZE;
RXCP->OWNER = 1U;
RXCP++;
RXCP = (char*)RXCP + 4; /* Here, don't know why data in buffer is 32 * 5 bytes while 3137 is 32 * 4 bytes, perhaps because of the lwIP protocol */
}
ECTRL_C0RXEN = 1U; /* Reactivate interrupts */
}
Can you help me analyze where the problem might be occurring? Thank you.