16
16
*
17
17
* Description: NUC472 MAC driver source file
18
18
*/
19
+ #include <stdbool.h>
19
20
#include "nuc472_eth.h"
20
21
#include "mbed_toolchain.h"
22
+ //#define NU_TRACE
21
23
#include "numaker_eth_hal.h"
22
24
23
25
#define ETH_TRIGGER_RX () do{EMAC->RXST = 0;}while(0)
24
26
#define ETH_TRIGGER_TX () do{EMAC->TXST = 0;}while(0)
25
27
#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)
27
29
#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)
29
31
32
+ #define EMAC_ENABLE_INT (emac , u32eIntSel ) ((emac)->INTEN |= (u32eIntSel))
33
+ #define EMAC_DISABLE_INT (emac , u32eIntSel ) ((emac)->INTEN &= ~ (u32eIntSel))
30
34
31
35
MBED_ALIGN (4 ) struct eth_descriptor rx_desc [RX_DESCRIPTOR_NUM ];
32
36
MBED_ALIGN (4 ) struct eth_descriptor tx_desc [TX_DESCRIPTOR_NUM ];
33
37
34
38
struct eth_descriptor volatile * cur_tx_desc_ptr , * cur_rx_desc_ptr , * fin_tx_desc_ptr ;
35
39
40
+ __attribute__ ((section ("EMAC_RAM" )))
36
41
MBED_ALIGN (4 ) uint8_t rx_buf [RX_DESCRIPTOR_NUM ][PACKET_BUFFER_SIZE ];
42
+ __attribute__ ((section ("EMAC_RAM" )))
37
43
MBED_ALIGN (4 ) uint8_t tx_buf [TX_DESCRIPTOR_NUM ][PACKET_BUFFER_SIZE ];
38
44
39
45
eth_callback_t nu_eth_txrx_cb = NULL ;
40
46
void * nu_userData = NULL ;
41
47
42
48
extern void ack_emac_rx_isr (void );
49
+ static bool isPhyReset = false;
50
+ static uint16_t phyLPAval = 0 ;
43
51
44
52
// PTP source clock is 84MHz (Real chip using PLL). Each tick is 11.90ns
45
53
// Assume we want to set each tick to 100ns.
@@ -113,6 +121,7 @@ static int reset_phy(void)
113
121
return (-1 );
114
122
} else {
115
123
reg = mdio_read (CONFIG_PHY_ADDR , MII_LPA );
124
+ phyLPAval = reg ;
116
125
117
126
if (reg & ADVERTISE_100FULL ) {
118
127
NU_DEBUGF (("100 full\n" ));
@@ -164,7 +173,7 @@ static void init_rx_desc(void)
164
173
rx_desc [i ].status1 = OWNERSHIP_EMAC ;
165
174
rx_desc [i ].buf = & rx_buf [i ][0 ];
166
175
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 ) ];
168
177
}
169
178
EMAC -> RXDSA = (unsigned int )& rx_desc [0 ];
170
179
return ;
@@ -188,10 +197,14 @@ void numaker_set_mac_addr(uint8_t *addr)
188
197
189
198
static void __eth_clk_pin_init ()
190
199
{
200
+ /* Unlock protected registers */
201
+ SYS_UnlockReg ();
191
202
/* Enable IP clock */
192
203
CLK_EnableModuleClock (EMAC_MODULE );
193
204
// Configure MDC clock rate to HCLK / (127 + 1) = 656 kHz if system is running at 84 MHz
194
205
CLK_SetModuleClock (EMAC_MODULE , 0 , CLK_CLKDIV3_EMAC (127 ));
206
+ /* Update System Core Clock */
207
+ SystemCoreClockUpdate ();
195
208
/*---------------------------------------------------------------------------------------------------------*/
196
209
/* Init I/O Multi-function */
197
210
/*---------------------------------------------------------------------------------------------------------*/
@@ -216,6 +229,8 @@ static void __eth_clk_pin_init()
216
229
SYS -> GPB_MFPH &= ~(SYS_GPB_MFPH_PB14MFP_Msk | SYS_GPB_MFPH_PB15MFP_Msk );
217
230
SYS -> GPB_MFPH |= SYS_GPB_MFPH_PB14MFP_EMAC_MII_MDC | SYS_GPB_MFPH_PB15MFP_EMAC_MII_MDIO ;
218
231
232
+ /* Lock protected registers */
233
+ SYS_LockReg ();
219
234
}
220
235
221
236
void numaker_eth_init (uint8_t * mac_addr )
@@ -225,15 +240,13 @@ void numaker_eth_init(uint8_t *mac_addr)
225
240
226
241
// Reset MAC
227
242
EMAC -> CTL = EMAC_CTL_RST_Msk ;
243
+ while (EMAC -> CTL & EMAC_CTL_RST_Msk ) {}
228
244
229
245
init_tx_desc ();
230
246
init_rx_desc ();
231
247
232
248
numaker_set_mac_addr (mac_addr ); // need to reconfigure hardware address 'cos we just RESET emc...
233
249
234
- /* Limit the max receive frame length to 1514 + 4 */
235
- EMAC -> MRFL = NU_ETH_MAX_FLEN ;
236
- reset_phy ();
237
250
238
251
EMAC -> CTL |= EMAC_CTL_STRIPCRC_Msk | EMAC_CTL_RXON_Msk | EMAC_CTL_TXON_Msk | EMAC_CTL_RMIIEN_Msk | EMAC_CTL_RMIIRXCTL_Msk ;
239
252
EMAC -> INTEN |= EMAC_INTEN_RXIEN_Msk |
@@ -244,7 +257,36 @@ void numaker_eth_init(uint8_t *mac_addr)
244
257
EMAC_INTEN_TXABTIEN_Msk |
245
258
EMAC_INTEN_TXCPIEN_Msk |
246
259
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
+
248
290
}
249
291
250
292
@@ -259,20 +301,22 @@ unsigned int m_status;
259
301
260
302
void EMAC_RX_IRQHandler (void )
261
303
{
262
- // NU_DEBUGF(("%s ... nu_eth_txrx_cb=0x%x\r\n", __FUNCTION__, nu_eth_txrx_cb));
263
304
m_status = EMAC -> INTSTS & 0xFFFF ;
264
305
EMAC -> INTSTS = m_status ;
265
306
if (m_status & EMAC_INTSTS_RXBEIF_Msk ) {
266
307
// 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 ;
269
311
}
312
+ EMAC_DISABLE_INT (EMAC , (EMAC_INTEN_RDUIEN_Msk | EMAC_INTEN_RXGDIEN_Msk ));
270
313
if (nu_eth_txrx_cb != NULL ) nu_eth_txrx_cb ('R' , nu_userData );
271
314
}
272
315
273
316
274
317
void numaker_eth_trigger_rx (void )
275
318
{
319
+ EMAC_ENABLE_INT (EMAC , (EMAC_INTEN_RDUIEN_Msk | EMAC_INTEN_RXGDIEN_Msk ));
276
320
ETH_TRIGGER_RX ();
277
321
}
278
322
@@ -291,6 +335,12 @@ int numaker_eth_get_rx_buf(uint16_t *len, uint8_t **buf)
291
335
if (status & RXFD_RXGD ) {
292
336
* buf = cur_rx_desc_ptr -> buf ;
293
337
* 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 ));
294
344
}
295
345
return 0 ;
296
346
}
@@ -309,6 +359,8 @@ void EMAC_TX_IRQHandler(void)
309
359
EMAC -> INTSTS = status ;
310
360
if (status & EMAC_INTSTS_TXBEIF_Msk ) {
311
361
// 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 );
312
364
return ;
313
365
}
314
366
0 commit comments