Skip to content

Commit 68e9f4a

Browse files
committed
NUC472 support EMAC bus reset as while bus error
1 parent 16dacb7 commit 68e9f4a

File tree

1 file changed

+62
-10
lines changed
  • features/netsocket/emac-drivers/TARGET_NUVOTON_EMAC/TARGET_NUC472

1 file changed

+62
-10
lines changed

features/netsocket/emac-drivers/TARGET_NUVOTON_EMAC/TARGET_NUC472/nuc472_eth.c

Lines changed: 62 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,30 +16,38 @@
1616
*
1717
* Description: NUC472 MAC driver source file
1818
*/
19+
#include <stdbool.h>
1920
#include "nuc472_eth.h"
2021
#include "mbed_toolchain.h"
22+
//#define NU_TRACE
2123
#include "numaker_eth_hal.h"
2224

2325
#define ETH_TRIGGER_RX() do{EMAC->RXST = 0;}while(0)
2426
#define ETH_TRIGGER_TX() do{EMAC->TXST = 0;}while(0)
2527
#define ETH_ENABLE_TX() do{EMAC->CTL |= EMAC_CTL_TXON;}while(0)
26-
#define ETH_ENABLE_RX() do{EMAC->CTL |= EMAC_CTL_RXON;}while(0)
28+
#define ETH_ENABLE_RX() do{EMAC->CTL |= EMAC_CTL_RXON_Msk;}while(0)
2729
#define ETH_DISABLE_TX() do{EMAC->CTL &= ~EMAC_CTL_TXON;}while(0)
28-
#define ETH_DISABLE_RX() do{EMAC->CTL &= ~EMAC_CTL_RXON;}while(0)
30+
#define ETH_DISABLE_RX() do{EMAC->CTL &= ~EMAC_CTL_RXON_Msk;}while(0)
2931

32+
#define EMAC_ENABLE_INT(emac, u32eIntSel) ((emac)->INTEN |= (u32eIntSel))
33+
#define EMAC_DISABLE_INT(emac, u32eIntSel) ((emac)->INTEN &= ~ (u32eIntSel))
3034

3135
MBED_ALIGN(4) struct eth_descriptor rx_desc[RX_DESCRIPTOR_NUM];
3236
MBED_ALIGN(4) struct eth_descriptor tx_desc[TX_DESCRIPTOR_NUM];
3337

3438
struct eth_descriptor volatile *cur_tx_desc_ptr, *cur_rx_desc_ptr, *fin_tx_desc_ptr;
3539

40+
__attribute__ ((section("EMAC_RAM")))
3641
MBED_ALIGN(4) uint8_t rx_buf[RX_DESCRIPTOR_NUM][PACKET_BUFFER_SIZE];
42+
__attribute__ ((section("EMAC_RAM")))
3743
MBED_ALIGN(4) uint8_t tx_buf[TX_DESCRIPTOR_NUM][PACKET_BUFFER_SIZE];
3844

3945
eth_callback_t nu_eth_txrx_cb = NULL;
4046
void *nu_userData = NULL;
4147

4248
extern void ack_emac_rx_isr(void);
49+
static bool isPhyReset = false;
50+
static uint16_t phyLPAval = 0;
4351

4452
// PTP source clock is 84MHz (Real chip using PLL). Each tick is 11.90ns
4553
// Assume we want to set each tick to 100ns.
@@ -113,6 +121,7 @@ static int reset_phy(void)
113121
return(-1);
114122
} else {
115123
reg = mdio_read(CONFIG_PHY_ADDR, MII_LPA);
124+
phyLPAval = reg;
116125

117126
if(reg & ADVERTISE_100FULL) {
118127
NU_DEBUGF(("100 full\n"));
@@ -164,7 +173,7 @@ static void init_rx_desc(void)
164173
rx_desc[i].status1 = OWNERSHIP_EMAC;
165174
rx_desc[i].buf = &rx_buf[i][0];
166175
rx_desc[i].status2 = 0;
167-
rx_desc[i].next = &rx_desc[(i + 1) % TX_DESCRIPTOR_NUM];
176+
rx_desc[i].next = &rx_desc[(i + 1) % (RX_DESCRIPTOR_NUM)];
168177
}
169178
EMAC->RXDSA = (unsigned int)&rx_desc[0];
170179
return;
@@ -188,10 +197,14 @@ void numaker_set_mac_addr(uint8_t *addr)
188197

189198
static void __eth_clk_pin_init()
190199
{
200+
/* Unlock protected registers */
201+
SYS_UnlockReg();
191202
/* Enable IP clock */
192203
CLK_EnableModuleClock(EMAC_MODULE);
193204
// Configure MDC clock rate to HCLK / (127 + 1) = 656 kHz if system is running at 84 MHz
194205
CLK_SetModuleClock(EMAC_MODULE, 0, CLK_CLKDIV3_EMAC(127));
206+
/* Update System Core Clock */
207+
SystemCoreClockUpdate();
195208
/*---------------------------------------------------------------------------------------------------------*/
196209
/* Init I/O Multi-function */
197210
/*---------------------------------------------------------------------------------------------------------*/
@@ -216,6 +229,8 @@ static void __eth_clk_pin_init()
216229
SYS->GPB_MFPH &= ~(SYS_GPB_MFPH_PB14MFP_Msk | SYS_GPB_MFPH_PB15MFP_Msk);
217230
SYS->GPB_MFPH |= SYS_GPB_MFPH_PB14MFP_EMAC_MII_MDC | SYS_GPB_MFPH_PB15MFP_EMAC_MII_MDIO;
218231

232+
/* Lock protected registers */
233+
SYS_LockReg();
219234
}
220235

221236
void numaker_eth_init(uint8_t *mac_addr)
@@ -225,15 +240,13 @@ void numaker_eth_init(uint8_t *mac_addr)
225240

226241
// Reset MAC
227242
EMAC->CTL = EMAC_CTL_RST_Msk;
243+
while(EMAC->CTL & EMAC_CTL_RST_Msk) {}
228244

229245
init_tx_desc();
230246
init_rx_desc();
231247

232248
numaker_set_mac_addr(mac_addr); // need to reconfigure hardware address 'cos we just RESET emc...
233249

234-
/* Limit the max receive frame length to 1514 + 4 */
235-
EMAC->MRFL = NU_ETH_MAX_FLEN;
236-
reset_phy();
237250

238251
EMAC->CTL |= EMAC_CTL_STRIPCRC_Msk | EMAC_CTL_RXON_Msk | EMAC_CTL_TXON_Msk | EMAC_CTL_RMIIEN_Msk | EMAC_CTL_RMIIRXCTL_Msk;
239252
EMAC->INTEN |= EMAC_INTEN_RXIEN_Msk |
@@ -244,7 +257,36 @@ void numaker_eth_init(uint8_t *mac_addr)
244257
EMAC_INTEN_TXABTIEN_Msk |
245258
EMAC_INTEN_TXCPIEN_Msk |
246259
EMAC_INTEN_TXBEIEN_Msk;
247-
EMAC->RXST = 0; // trigger Rx
260+
/* Limit the max receive frame length to 1514 + 4 */
261+
EMAC->MRFL = NU_ETH_MAX_FLEN;
262+
263+
/* Set RX FIFO threshold as 8 words */
264+
265+
if (isPhyReset != true)
266+
{
267+
if (!reset_phy())
268+
{
269+
isPhyReset = true;
270+
}
271+
} else {
272+
if (phyLPAval & ADVERTISE_100FULL) {
273+
NU_DEBUGF(("100 full\n"));
274+
EMAC->CTL |= (EMAC_CTL_OPMODE_Msk | EMAC_CTL_FUDUP_Msk);
275+
} else if (phyLPAval & ADVERTISE_100HALF) {
276+
NU_DEBUGF(("100 half\n"));
277+
EMAC->CTL = (EMAC->CTL & ~EMAC_CTL_FUDUP_Msk) | EMAC_CTL_OPMODE_Msk;
278+
} else if (phyLPAval & ADVERTISE_10FULL) {
279+
NU_DEBUGF(("10 full\n"));
280+
EMAC->CTL = (EMAC->CTL & ~EMAC_CTL_OPMODE_Msk) | EMAC_CTL_FUDUP_Msk;
281+
} else {
282+
NU_DEBUGF(("10 half\n"));
283+
EMAC->CTL &= ~(EMAC_CTL_OPMODE_Msk | EMAC_CTL_FUDUP_Msk);
284+
}
285+
}
286+
287+
EMAC_ENABLE_RX();
288+
EMAC_ENABLE_TX();
289+
248290
}
249291

250292

@@ -259,20 +301,22 @@ unsigned int m_status;
259301

260302
void EMAC_RX_IRQHandler(void)
261303
{
262-
// NU_DEBUGF(("%s ... nu_eth_txrx_cb=0x%x\r\n", __FUNCTION__, nu_eth_txrx_cb));
263304
m_status = EMAC->INTSTS & 0xFFFF;
264305
EMAC->INTSTS = m_status;
265306
if (m_status & EMAC_INTSTS_RXBEIF_Msk) {
266307
// Shouldn't goes here, unless descriptor corrupted
267-
NU_DEBUGF(("RX descriptor corrupted \r\n"));
268-
//return;
308+
mbed_error_printf("### RX Bus error [0x%x]\r\n", m_status);
309+
if (nu_eth_txrx_cb != NULL) nu_eth_txrx_cb('B', nu_userData);
310+
return;
269311
}
312+
EMAC_DISABLE_INT(EMAC, (EMAC_INTEN_RDUIEN_Msk | EMAC_INTEN_RXGDIEN_Msk));
270313
if (nu_eth_txrx_cb != NULL) nu_eth_txrx_cb('R', nu_userData);
271314
}
272315

273316

274317
void numaker_eth_trigger_rx(void)
275318
{
319+
EMAC_ENABLE_INT(EMAC, (EMAC_INTEN_RDUIEN_Msk | EMAC_INTEN_RXGDIEN_Msk));
276320
ETH_TRIGGER_RX();
277321
}
278322

@@ -291,6 +335,12 @@ int numaker_eth_get_rx_buf(uint16_t *len, uint8_t **buf)
291335
if (status & RXFD_RXGD) {
292336
*buf = cur_rx_desc_ptr->buf;
293337
*len = status & 0xFFFF;
338+
// length of payload should be <= 1514
339+
if ( *len > (NU_ETH_MAX_FLEN - 4) ) {
340+
NU_DEBUGF(("%s... unexpected long packet length=%d, buf=0x%x\r\n", __FUNCTION__, *len, *buf));
341+
*len = 0; // Skip this unexpected long packet
342+
}
343+
if (*len == (NU_ETH_MAX_FLEN - 4)) NU_DEBUGF(("%s... length=%d, buf=0x%x\r\n", __FUNCTION__, *len, *buf));
294344
}
295345
return 0;
296346
}
@@ -309,6 +359,8 @@ void EMAC_TX_IRQHandler(void)
309359
EMAC->INTSTS = status;
310360
if(status & EMAC_INTSTS_TXBEIF_Msk) {
311361
// Shouldn't goes here, unless descriptor corrupted
362+
mbed_error_printf("### TX Bus error [0x%x]\r\n", status);
363+
if (nu_eth_txrx_cb != NULL) nu_eth_txrx_cb('B', nu_userData);
312364
return;
313365
}
314366

0 commit comments

Comments
 (0)