Skip to content

Commit 16e447e

Browse files
committed
NUC472 support EMAC bus reset as while bus error
1 parent 54b3417 commit 16e447e

File tree

1 file changed

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

1 file changed

+62
-8
lines changed

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

Lines changed: 62 additions & 8 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.
@@ -111,6 +119,7 @@ static int reset_phy(void)
111119
return(-1);
112120
} else {
113121
reg = mdio_read(CONFIG_PHY_ADDR, MII_LPA);
122+
phyLPAval = reg;
114123

115124
if(reg & ADVERTISE_100FULL) {
116125
NU_DEBUGF(("100 full\n"));
@@ -162,7 +171,7 @@ static void init_rx_desc(void)
162171
rx_desc[i].status1 = OWNERSHIP_EMAC;
163172
rx_desc[i].buf = &rx_buf[i][0];
164173
rx_desc[i].status2 = 0;
165-
rx_desc[i].next = &rx_desc[(i + 1) % TX_DESCRIPTOR_NUM];
174+
rx_desc[i].next = &rx_desc[(i + 1) % (RX_DESCRIPTOR_NUM)];
166175
}
167176
EMAC->RXDSA = (unsigned int)&rx_desc[0];
168177
return;
@@ -186,10 +195,14 @@ void numaker_set_mac_addr(uint8_t *addr)
186195

187196
static void __eth_clk_pin_init()
188197
{
198+
/* Unlock protected registers */
199+
SYS_UnlockReg();
189200
/* Enable IP clock */
190201
CLK_EnableModuleClock(EMAC_MODULE);
191202
// Configure MDC clock rate to HCLK / (127 + 1) = 656 kHz if system is running at 84 MHz
192203
CLK_SetModuleClock(EMAC_MODULE, 0, CLK_CLKDIV3_EMAC(127));
204+
/* Update System Core Clock */
205+
SystemCoreClockUpdate();
193206
/*---------------------------------------------------------------------------------------------------------*/
194207
/* Init I/O Multi-function */
195208
/*---------------------------------------------------------------------------------------------------------*/
@@ -214,6 +227,8 @@ static void __eth_clk_pin_init()
214227
SYS->GPB_MFPH &= ~(SYS_GPB_MFPH_PB14MFP_Msk | SYS_GPB_MFPH_PB15MFP_Msk);
215228
SYS->GPB_MFPH |= SYS_GPB_MFPH_PB14MFP_EMAC_MII_MDC | SYS_GPB_MFPH_PB15MFP_EMAC_MII_MDIO;
216229

230+
/* Lock protected registers */
231+
SYS_LockReg();
217232
}
218233

219234
void numaker_eth_init(uint8_t *mac_addr)
@@ -223,12 +238,12 @@ void numaker_eth_init(uint8_t *mac_addr)
223238

224239
// Reset MAC
225240
EMAC->CTL = EMAC_CTL_RST_Msk;
241+
while(EMAC->CTL & EMAC_CTL_RST_Msk) {}
226242

227243
init_tx_desc();
228244
init_rx_desc();
229245

230246
numaker_set_mac_addr(mac_addr); // need to reconfigure hardware address 'cos we just RESET emc...
231-
reset_phy();
232247

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

245289

@@ -254,20 +298,22 @@ unsigned int m_status;
254298

255299
void EMAC_RX_IRQHandler(void)
256300
{
257-
// NU_DEBUGF(("%s ... nu_eth_txrx_cb=0x%x\r\n", __FUNCTION__, nu_eth_txrx_cb));
258301
m_status = EMAC->INTSTS & 0xFFFF;
259302
EMAC->INTSTS = m_status;
260303
if (m_status & EMAC_INTSTS_RXBEIF_Msk) {
261304
// Shouldn't goes here, unless descriptor corrupted
262-
NU_DEBUGF(("RX descriptor corrupted \r\n"));
263-
//return;
305+
mbed_error_printf("### RX Bus error [0x%x]\r\n", m_status);
306+
if (nu_eth_txrx_cb != NULL) nu_eth_txrx_cb('B', nu_userData);
307+
return;
264308
}
309+
EMAC_DISABLE_INT(EMAC, (EMAC_INTEN_RDUIEN_Msk | EMAC_INTEN_RXGDIEN_Msk));
265310
if (nu_eth_txrx_cb != NULL) nu_eth_txrx_cb('R', nu_userData);
266311
}
267312

268313

269314
void numaker_eth_trigger_rx(void)
270315
{
316+
EMAC_ENABLE_INT(EMAC, (EMAC_INTEN_RDUIEN_Msk | EMAC_INTEN_RXGDIEN_Msk));
271317
ETH_TRIGGER_RX();
272318
}
273319

@@ -286,6 +332,12 @@ int numaker_eth_get_rx_buf(uint16_t *len, uint8_t **buf)
286332
if (status & RXFD_RXGD) {
287333
*buf = cur_rx_desc_ptr->buf;
288334
*len = status & 0xFFFF;
335+
// length of payload should be <= 1514
336+
if ( *len > (NU_ETH_MAX_FLEN - 4) ) {
337+
NU_DEBUGF(("%s... unexpected long packet length=%d, buf=0x%x\r\n", __FUNCTION__, *len, *buf));
338+
*len = 0; // Skip this unexpected long packet
339+
}
340+
if (*len == (NU_ETH_MAX_FLEN - 4)) NU_DEBUGF(("%s... length=%d, buf=0x%x\r\n", __FUNCTION__, *len, *buf));
289341
}
290342
return 0;
291343
}
@@ -304,6 +356,8 @@ void EMAC_TX_IRQHandler(void)
304356
EMAC->INTSTS = status;
305357
if(status & EMAC_INTSTS_TXBEIF_Msk) {
306358
// Shouldn't goes here, unless descriptor corrupted
359+
mbed_error_printf("### TX Bus error [0x%x]\r\n", status);
360+
if (nu_eth_txrx_cb != NULL) nu_eth_txrx_cb('B', nu_userData);
307361
return;
308362
}
309363

0 commit comments

Comments
 (0)