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.
@@ -111,6 +119,7 @@ static int reset_phy(void)
111
119
return (-1 );
112
120
} else {
113
121
reg = mdio_read (CONFIG_PHY_ADDR , MII_LPA );
122
+ phyLPAval = reg ;
114
123
115
124
if (reg & ADVERTISE_100FULL ) {
116
125
NU_DEBUGF (("100 full\n" ));
@@ -162,7 +171,7 @@ static void init_rx_desc(void)
162
171
rx_desc [i ].status1 = OWNERSHIP_EMAC ;
163
172
rx_desc [i ].buf = & rx_buf [i ][0 ];
164
173
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 ) ];
166
175
}
167
176
EMAC -> RXDSA = (unsigned int )& rx_desc [0 ];
168
177
return ;
@@ -186,10 +195,14 @@ void numaker_set_mac_addr(uint8_t *addr)
186
195
187
196
static void __eth_clk_pin_init ()
188
197
{
198
+ /* Unlock protected registers */
199
+ SYS_UnlockReg ();
189
200
/* Enable IP clock */
190
201
CLK_EnableModuleClock (EMAC_MODULE );
191
202
// Configure MDC clock rate to HCLK / (127 + 1) = 656 kHz if system is running at 84 MHz
192
203
CLK_SetModuleClock (EMAC_MODULE , 0 , CLK_CLKDIV3_EMAC (127 ));
204
+ /* Update System Core Clock */
205
+ SystemCoreClockUpdate ();
193
206
/*---------------------------------------------------------------------------------------------------------*/
194
207
/* Init I/O Multi-function */
195
208
/*---------------------------------------------------------------------------------------------------------*/
@@ -214,6 +227,8 @@ static void __eth_clk_pin_init()
214
227
SYS -> GPB_MFPH &= ~(SYS_GPB_MFPH_PB14MFP_Msk | SYS_GPB_MFPH_PB15MFP_Msk );
215
228
SYS -> GPB_MFPH |= SYS_GPB_MFPH_PB14MFP_EMAC_MII_MDC | SYS_GPB_MFPH_PB15MFP_EMAC_MII_MDIO ;
216
229
230
+ /* Lock protected registers */
231
+ SYS_LockReg ();
217
232
}
218
233
219
234
void numaker_eth_init (uint8_t * mac_addr )
@@ -223,12 +238,12 @@ void numaker_eth_init(uint8_t *mac_addr)
223
238
224
239
// Reset MAC
225
240
EMAC -> CTL = EMAC_CTL_RST_Msk ;
241
+ while (EMAC -> CTL & EMAC_CTL_RST_Msk ) {}
226
242
227
243
init_tx_desc ();
228
244
init_rx_desc ();
229
245
230
246
numaker_set_mac_addr (mac_addr ); // need to reconfigure hardware address 'cos we just RESET emc...
231
- reset_phy ();
232
247
233
248
EMAC -> CTL |= EMAC_CTL_STRIPCRC_Msk | EMAC_CTL_RXON_Msk | EMAC_CTL_TXON_Msk | EMAC_CTL_RMIIEN_Msk | EMAC_CTL_RMIIRXCTL_Msk ;
234
249
EMAC -> INTEN |= EMAC_INTEN_RXIEN_Msk |
@@ -239,7 +254,36 @@ void numaker_eth_init(uint8_t *mac_addr)
239
254
EMAC_INTEN_TXABTIEN_Msk |
240
255
EMAC_INTEN_TXCPIEN_Msk |
241
256
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
+
243
287
}
244
288
245
289
@@ -254,20 +298,22 @@ unsigned int m_status;
254
298
255
299
void EMAC_RX_IRQHandler (void )
256
300
{
257
- // NU_DEBUGF(("%s ... nu_eth_txrx_cb=0x%x\r\n", __FUNCTION__, nu_eth_txrx_cb));
258
301
m_status = EMAC -> INTSTS & 0xFFFF ;
259
302
EMAC -> INTSTS = m_status ;
260
303
if (m_status & EMAC_INTSTS_RXBEIF_Msk ) {
261
304
// 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 ;
264
308
}
309
+ EMAC_DISABLE_INT (EMAC , (EMAC_INTEN_RDUIEN_Msk | EMAC_INTEN_RXGDIEN_Msk ));
265
310
if (nu_eth_txrx_cb != NULL ) nu_eth_txrx_cb ('R' , nu_userData );
266
311
}
267
312
268
313
269
314
void numaker_eth_trigger_rx (void )
270
315
{
316
+ EMAC_ENABLE_INT (EMAC , (EMAC_INTEN_RDUIEN_Msk | EMAC_INTEN_RXGDIEN_Msk ));
271
317
ETH_TRIGGER_RX ();
272
318
}
273
319
@@ -286,6 +332,12 @@ int numaker_eth_get_rx_buf(uint16_t *len, uint8_t **buf)
286
332
if (status & RXFD_RXGD ) {
287
333
* buf = cur_rx_desc_ptr -> buf ;
288
334
* 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 ));
289
341
}
290
342
return 0 ;
291
343
}
@@ -304,6 +356,8 @@ void EMAC_TX_IRQHandler(void)
304
356
EMAC -> INTSTS = status ;
305
357
if (status & EMAC_INTSTS_TXBEIF_Msk ) {
306
358
// 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 );
307
361
return ;
308
362
}
309
363
0 commit comments