1
1
/*
2
- * Copyright (c) 2018 Nuvoton Technology Corp.
2
+ * Copyright (c) 2018 Nuvoton Technology Corp.
3
3
* Copyright (c) 2018 ARM Limited
4
4
*
5
5
* Licensed under the Apache License, Version 2.0 (the "License");
28
28
#define ETH_ENABLE_RX () do{EMAC->CTL |= EMAC_CTL_RXON_Msk;}while(0)
29
29
#define ETH_DISABLE_TX () do{EMAC->CTL &= ~EMAC_CTL_TXON;}while(0)
30
30
#define ETH_DISABLE_RX () do{EMAC->CTL &= ~EMAC_CTL_RXON_Msk;}while(0)
31
-
31
+
32
32
#define EMAC_ENABLE_INT (emac , u32eIntSel ) ((emac)->INTEN |= (u32eIntSel))
33
- #define EMAC_DISABLE_INT (emac , u32eIntSel ) ((emac)->INTEN &= ~ (u32eIntSel))
33
+ #define EMAC_DISABLE_INT (emac , u32eIntSel ) ((emac)->INTEN &= ~ (u32eIntSel))
34
34
35
35
MBED_ALIGN (4 ) struct eth_descriptor rx_desc [RX_DESCRIPTOR_NUM ];
36
36
MBED_ALIGN (4 ) struct eth_descriptor tx_desc [TX_DESCRIPTOR_NUM ];
37
37
38
38
struct eth_descriptor volatile * cur_tx_desc_ptr , * cur_rx_desc_ptr , * fin_tx_desc_ptr ;
39
39
40
- __attribute__ ((section ("EMAC_RAM" )))
40
+ __attribute__((section ("EMAC_RAM" )))
41
41
MBED_ALIGN (4 ) uint8_t rx_buf [RX_DESCRIPTOR_NUM ][PACKET_BUFFER_SIZE ];
42
- __attribute__ ((section ("EMAC_RAM" )))
42
+ __attribute__((section ("EMAC_RAM" )))
43
43
MBED_ALIGN (4 ) uint8_t tx_buf [TX_DESCRIPTOR_NUM ][PACKET_BUFFER_SIZE ];
44
44
45
45
eth_callback_t nu_eth_txrx_cb = NULL ;
@@ -74,7 +74,7 @@ static uint16_t mdio_read(uint8_t addr, uint8_t reg)
74
74
EMAC -> MIIMCTL = (addr << EMAC_MIIMCTL_PHYADDR_Pos ) | reg | EMAC_MIIMCTL_BUSY_Msk | EMAC_MIIMCTL_MDCON_Msk ;
75
75
while (EMAC -> MIIMCTL & EMAC_MIIMCTL_BUSY_Msk );
76
76
77
- return (EMAC -> MIIMDAT );
77
+ return (EMAC -> MIIMDAT );
78
78
}
79
79
80
80
static int reset_phy (void )
@@ -87,15 +87,18 @@ static int reset_phy(void)
87
87
mdio_write (CONFIG_PHY_ADDR , MII_BMCR , BMCR_RESET );
88
88
89
89
delayCnt = 2000 ;
90
- while (delayCnt -- > 0 ) {
91
- if ((mdio_read (CONFIG_PHY_ADDR , MII_BMCR ) & BMCR_RESET ) == 0 )
90
+
91
+ while (delayCnt > 0 ) {
92
+ delayCnt -- ;
93
+ if ((mdio_read (CONFIG_PHY_ADDR , MII_BMCR ) & BMCR_RESET ) == 0 ) {
92
94
break ;
95
+ }
93
96
94
97
}
95
98
96
- if (delayCnt == 0 ) {
99
+ if (delayCnt == 0 ) {
97
100
NU_DEBUGF (("Reset phy failed\n" ));
98
- return (-1 );
101
+ return (-1 );
99
102
}
100
103
101
104
mdio_write (CONFIG_PHY_ADDR , MII_ADVERTISE , ADVERTISE_CSMA |
@@ -108,38 +111,41 @@ static int reset_phy(void)
108
111
mdio_write (CONFIG_PHY_ADDR , MII_BMCR , reg | BMCR_ANRESTART );
109
112
110
113
delayCnt = 200000 ;
111
- while (delayCnt -- > 0 ) {
112
- if ((mdio_read (CONFIG_PHY_ADDR , MII_BMSR ) & (BMSR_ANEGCOMPLETE | BMSR_LSTATUS ))
113
- == (BMSR_ANEGCOMPLETE | BMSR_LSTATUS ))
114
+
115
+ while (delayCnt > 0 ) {
116
+ delayCnt -- ;
117
+ if ((mdio_read (CONFIG_PHY_ADDR , MII_BMSR ) & (BMSR_ANEGCOMPLETE | BMSR_LSTATUS ))
118
+ == (BMSR_ANEGCOMPLETE | BMSR_LSTATUS )) {
114
119
break ;
120
+ }
115
121
}
116
122
117
- if (delayCnt == 0 ) {
123
+ if (delayCnt == 0 ) {
118
124
NU_DEBUGF (("AN failed. Set to 100 FULL\n" ));
119
125
EMAC -> CTL |= (EMAC_CTL_OPMODE_Msk | EMAC_CTL_FUDUP_Msk );
120
- return (-1 );
126
+ return (-1 );
121
127
} else {
122
128
reg = mdio_read (CONFIG_PHY_ADDR , MII_LPA );
123
129
phyLPAval = reg ;
124
130
125
- if (reg & ADVERTISE_100FULL ) {
131
+ if (reg & ADVERTISE_100FULL ) {
126
132
NU_DEBUGF (("100 full\n" ));
127
133
EMAC -> CTL |= (EMAC_CTL_OPMODE_Msk | EMAC_CTL_FUDUP_Msk );
128
- } else if (reg & ADVERTISE_100HALF ) {
134
+ } else if (reg & ADVERTISE_100HALF ) {
129
135
NU_DEBUGF (("100 half\n" ));
130
136
EMAC -> CTL = (EMAC -> CTL & ~EMAC_CTL_FUDUP_Msk ) | EMAC_CTL_OPMODE_Msk ;
131
- } else if (reg & ADVERTISE_10FULL ) {
137
+ } else if (reg & ADVERTISE_10FULL ) {
132
138
NU_DEBUGF (("10 full\n" ));
133
139
EMAC -> CTL = (EMAC -> CTL & ~EMAC_CTL_OPMODE_Msk ) | EMAC_CTL_FUDUP_Msk ;
134
140
} else {
135
141
NU_DEBUGF (("10 half\n" ));
136
142
EMAC -> CTL &= ~(EMAC_CTL_OPMODE_Msk | EMAC_CTL_FUDUP_Msk );
137
143
}
138
144
}
139
- printf ("PHY ID 1:0x%x\r\n" , mdio_read (CONFIG_PHY_ADDR , MII_PHYSID1 ));
140
- printf ("PHY ID 2:0x%x\r\n" , mdio_read (CONFIG_PHY_ADDR , MII_PHYSID2 ));
145
+ printf ("PHY ID 1:0x%x\r\n" , mdio_read (CONFIG_PHY_ADDR , MII_PHYSID1 ));
146
+ printf ("PHY ID 2:0x%x\r\n" , mdio_read (CONFIG_PHY_ADDR , MII_PHYSID2 ));
141
147
142
- return (0 );
148
+ return (0 );
143
149
}
144
150
145
151
@@ -150,7 +156,7 @@ static void init_tx_desc(void)
150
156
151
157
cur_tx_desc_ptr = fin_tx_desc_ptr = & tx_desc [0 ];
152
158
153
- for (i = 0 ; i < TX_DESCRIPTOR_NUM ; i ++ ) {
159
+ for (i = 0 ; i < TX_DESCRIPTOR_NUM ; i ++ ) {
154
160
tx_desc [i ].status1 = TXFD_PADEN | TXFD_CRCAPP | TXFD_INTEN ;
155
161
tx_desc [i ].buf = & tx_buf [i ][0 ];
156
162
tx_desc [i ].status2 = 0 ;
@@ -168,7 +174,7 @@ static void init_rx_desc(void)
168
174
169
175
cur_rx_desc_ptr = & rx_desc [0 ];
170
176
171
- for (i = 0 ; i < RX_DESCRIPTOR_NUM ; i ++ ) {
177
+ for (i = 0 ; i < RX_DESCRIPTOR_NUM ; i ++ ) {
172
178
rx_desc [i ].status1 = OWNERSHIP_EMAC ;
173
179
rx_desc [i ].buf = & rx_buf [i ][0 ];
174
180
rx_desc [i ].status2 = 0 ;
@@ -199,13 +205,13 @@ static void __eth_clk_pin_init()
199
205
200
206
/* Enable IP clock */
201
207
CLK_EnableModuleClock (EMAC_MODULE );
202
-
208
+
203
209
// Configure MDC clock rate to HCLK / (127 + 1) = 1.25 MHz if system is running at 160 MH
204
210
CLK_SetModuleClock (EMAC_MODULE , 0 , CLK_CLKDIV3_EMAC (127 ));
205
-
211
+
206
212
/* Update System Core Clock */
207
213
SystemCoreClockUpdate ();
208
-
214
+
209
215
/*---------------------------------------------------------------------------------------------------------*/
210
216
/* Init I/O Multi-function */
211
217
/*---------------------------------------------------------------------------------------------------------*/
@@ -219,10 +225,10 @@ static void __eth_clk_pin_init()
219
225
SYS -> GPE_MFPH &= ~(SYS_GPE_MFPH_PE8MFP_Msk | SYS_GPE_MFPH_PE9MFP_Msk | SYS_GPE_MFPH_PE10MFP_Msk |
220
226
SYS_GPE_MFPH_PE11MFP_Msk | SYS_GPE_MFPH_PE12MFP_Msk );
221
227
SYS -> GPE_MFPH |= SYS_GPE_MFPH_PE8MFP_EMAC_RMII_MDC |
222
- SYS_GPE_MFPH_PE9MFP_EMAC_RMII_MDIO |
223
- SYS_GPE_MFPH_PE10MFP_EMAC_RMII_TXD0 |
224
- SYS_GPE_MFPH_PE11MFP_EMAC_RMII_TXD1 |
225
- SYS_GPE_MFPH_PE12MFP_EMAC_RMII_TXEN ;
228
+ SYS_GPE_MFPH_PE9MFP_EMAC_RMII_MDIO |
229
+ SYS_GPE_MFPH_PE10MFP_EMAC_RMII_TXD0 |
230
+ SYS_GPE_MFPH_PE11MFP_EMAC_RMII_TXD1 |
231
+ SYS_GPE_MFPH_PE12MFP_EMAC_RMII_TXEN ;
226
232
227
233
// Enable high slew rate on all RMII TX output pins
228
234
PE -> SLEWCTL = (GPIO_SLEWCTL_HIGH << GPIO_SLEWCTL_HSREN10_Pos ) |
@@ -238,13 +244,13 @@ static void __eth_clk_pin_init()
238
244
239
245
void numaker_eth_init (uint8_t * mac_addr )
240
246
{
241
-
242
- // init CLK & pins
243
- __eth_clk_pin_init ();
244
-
247
+
248
+ // init CLK & pins
249
+ __eth_clk_pin_init ();
250
+
245
251
// Reset MAC
246
252
EMAC -> CTL = EMAC_CTL_RST_Msk ;
247
- while (EMAC -> CTL & EMAC_CTL_RST_Msk ) {}
253
+ while (EMAC -> CTL & EMAC_CTL_RST_Msk ) {}
248
254
249
255
init_tx_desc ();
250
256
init_rx_desc ();
@@ -270,17 +276,15 @@ void numaker_eth_init(uint8_t *mac_addr)
270
276
EMAC -> CAMCTL = EMAC_CAMCTL_CMPEN_Msk |
271
277
EMAC_CAMCTL_AMP_Msk |
272
278
EMAC_CAMCTL_ABP_Msk ;
273
- EMAC -> CAMEN = 1 ; // Enable CAM entry 0
279
+ EMAC -> CAMEN = 1 ; // Enable CAM entry 0
274
280
/* Limit the max receive frame length to 1514 + 4 */
275
281
EMAC -> MRFL = NU_ETH_MAX_FLEN ;
276
-
282
+
277
283
/* Set RX FIFO threshold as 8 words */
278
284
EMAC -> FIFOCTL = 0x00200100 ;
279
-
280
- if (isPhyReset != true)
281
- {
282
- if (!reset_phy ())
283
- {
285
+
286
+ if (isPhyReset != true) {
287
+ if (!reset_phy ()) {
284
288
isPhyReset = true;
285
289
}
286
290
} else {
@@ -296,9 +300,9 @@ void numaker_eth_init(uint8_t *mac_addr)
296
300
} else {
297
301
NU_DEBUGF (("10 half\n" ));
298
302
EMAC -> CTL &= ~(EMAC_CTL_OPMODE_Msk | EMAC_CTL_FUDUP_Msk );
299
- }
303
+ }
300
304
}
301
-
305
+
302
306
EMAC_ENABLE_RX ();
303
307
EMAC_ENABLE_TX ();
304
308
@@ -321,11 +325,15 @@ void EMAC_RX_IRQHandler(void)
321
325
if (m_status & EMAC_INTSTS_RXBEIF_Msk ) {
322
326
// Shouldn't goes here, unless descriptor corrupted
323
327
mbed_error_printf ("### RX Bus error [0x%x]\r\n" , m_status );
324
- if (nu_eth_txrx_cb != NULL ) nu_eth_txrx_cb ('B' , nu_userData );
328
+ if (nu_eth_txrx_cb != NULL ) {
329
+ nu_eth_txrx_cb ('B' , nu_userData );
330
+ }
325
331
return ;
326
332
}
327
333
EMAC_DISABLE_INT (EMAC , (EMAC_INTEN_RDUIEN_Msk | EMAC_INTEN_RXGDIEN_Msk ));
328
- if (nu_eth_txrx_cb != NULL ) nu_eth_txrx_cb ('R' , nu_userData );
334
+ if (nu_eth_txrx_cb != NULL ) {
335
+ nu_eth_txrx_cb ('R' , nu_userData );
336
+ }
329
337
}
330
338
331
339
@@ -340,42 +348,48 @@ int numaker_eth_get_rx_buf(uint16_t *len, uint8_t **buf)
340
348
unsigned int cur_entry , status ;
341
349
342
350
cur_entry = EMAC -> CRXDSA ;
343
- if ((cur_entry == (uint32_t )cur_rx_desc_ptr ) && (!(m_status & EMAC_INTSTS_RDUIF_Msk ))) // cur_entry may equal to cur_rx_desc_ptr if RDU occures
344
- return -1 ;
351
+ if ((cur_entry == (uint32_t )cur_rx_desc_ptr ) && (!(m_status & EMAC_INTSTS_RDUIF_Msk ))) { // cur_entry may equal to cur_rx_desc_ptr if RDU occures
352
+ return -1 ;
353
+ }
345
354
status = cur_rx_desc_ptr -> status1 ;
346
355
347
- if (status & OWNERSHIP_EMAC )
348
- return -1 ;
356
+ if (status & OWNERSHIP_EMAC ) {
357
+ return -1 ;
358
+ }
349
359
350
360
if (status & RXFD_RXGD ) {
351
361
* buf = cur_rx_desc_ptr -> buf ;
352
362
* len = status & 0xFFFF ;
353
363
// length of payload should be <= 1514
354
- if ( * len > (NU_ETH_MAX_FLEN - 4 ) ) {
364
+ if (* len > (NU_ETH_MAX_FLEN - 4 )) {
355
365
NU_DEBUGF (("%s... unexpected long packet length=%d, buf=0x%x\r\n" , __FUNCTION__ , * len , * buf ));
356
366
* len = 0 ; // Skip this unexpected long packet
357
367
}
358
- if (* len == (NU_ETH_MAX_FLEN - 4 )) NU_DEBUGF (("%s... length=%d, buf=0x%x\r\n" , __FUNCTION__ , * len , * buf ));
368
+ if (* len == (NU_ETH_MAX_FLEN - 4 )) {
369
+ NU_DEBUGF (("%s... length=%d, buf=0x%x\r\n" , __FUNCTION__ , * len , * buf ));
370
+ }
359
371
}
360
372
return 0 ;
361
- }
373
+ }
362
374
363
375
void numaker_eth_rx_next (void )
364
376
{
365
377
cur_rx_desc_ptr -> status1 = OWNERSHIP_EMAC ;
366
- cur_rx_desc_ptr = cur_rx_desc_ptr -> next ;
367
- }
378
+ cur_rx_desc_ptr = cur_rx_desc_ptr -> next ;
379
+ }
368
380
369
381
void EMAC_TX_IRQHandler (void )
370
382
{
371
383
unsigned int cur_entry , status ;
372
384
373
385
status = EMAC -> INTSTS & 0xFFFF0000 ;
374
386
EMAC -> INTSTS = status ;
375
- if (status & EMAC_INTSTS_TXBEIF_Msk ) {
387
+ if (status & EMAC_INTSTS_TXBEIF_Msk ) {
376
388
// Shouldn't goes here, unless descriptor corrupted
377
389
mbed_error_printf ("### TX Bus error [0x%x]\r\n" , status );
378
- if (nu_eth_txrx_cb != NULL ) nu_eth_txrx_cb ('B' , nu_userData );
390
+ if (nu_eth_txrx_cb != NULL ) {
391
+ nu_eth_txrx_cb ('B' , nu_userData );
392
+ }
379
393
return ;
380
394
}
381
395
@@ -385,16 +399,19 @@ void EMAC_TX_IRQHandler(void)
385
399
386
400
fin_tx_desc_ptr = fin_tx_desc_ptr -> next ;
387
401
}
388
-
389
- if (nu_eth_txrx_cb != NULL ) nu_eth_txrx_cb ('T' , nu_userData );
402
+
403
+ if (nu_eth_txrx_cb != NULL ) {
404
+ nu_eth_txrx_cb ('T' , nu_userData );
405
+ }
390
406
}
391
407
392
408
uint8_t * numaker_eth_get_tx_buf (void )
393
409
{
394
- if (cur_tx_desc_ptr -> status1 & OWNERSHIP_EMAC )
395
- return (NULL );
396
- else
397
- return (cur_tx_desc_ptr -> buf );
410
+ if (cur_tx_desc_ptr -> status1 & OWNERSHIP_EMAC ) {
411
+ return (NULL );
412
+ } else {
413
+ return (cur_tx_desc_ptr -> buf );
414
+ }
398
415
}
399
416
400
417
void numaker_eth_trigger_tx (uint16_t length , void * p )
@@ -411,11 +428,12 @@ void numaker_eth_trigger_tx(uint16_t length, void *p)
411
428
412
429
int numaker_eth_link_ok (void )
413
430
{
414
- /* first, a dummy read to latch */
415
- mdio_read (CONFIG_PHY_ADDR , MII_BMSR );
416
- if (mdio_read (CONFIG_PHY_ADDR , MII_BMSR ) & BMSR_LSTATUS )
417
- return 1 ;
418
- return 0 ;
431
+ /* first, a dummy read to latch */
432
+ mdio_read (CONFIG_PHY_ADDR , MII_BMSR );
433
+ if (mdio_read (CONFIG_PHY_ADDR , MII_BMSR ) & BMSR_LSTATUS ) {
434
+ return 1 ;
435
+ }
436
+ return 0 ;
419
437
}
420
438
421
439
void numaker_eth_set_cb (eth_callback_t eth_cb , void * userData )
@@ -437,43 +455,44 @@ void mbed_mac_address(char *mac)
437
455
// http://en.wikipedia.org/wiki/MAC_address
438
456
uint32_t word1 = * (uint32_t * )0x7F800 ; // 2KB Data Flash at 0x7F800
439
457
440
- if ( word0 == 0xFFFFFFFF ) // Not burn any mac address at 1st 2 words of Data Flash
441
- {
458
+ if (word0 == 0xFFFFFFFF ) { // Not burn any mac address at 1st 2 words of Data Flash
442
459
// with a semi-unique MAC address from the UUID
443
460
/* Enable FMC ISP function */
444
461
SYS_UnlockReg ();
445
462
FMC_Open ();
446
463
// = FMC_ReadUID(0);
447
464
uID1 = FMC_ReadUID (1 );
448
465
word1 = (uID1 & 0x003FFFFF ) | ((uID1 & 0x030000 ) << 6 ) >> 8 ;
449
- word0 = ((FMC_ReadUID (0 ) >> 4 ) << 20 ) | ((uID1 & 0xFF )<< 12 ) | (FMC_ReadUID (2 ) & 0xFFF );
466
+ word0 = ((FMC_ReadUID (0 ) >> 4 ) << 20 ) | ((uID1 & 0xFF ) << 12 ) | (FMC_ReadUID (2 ) & 0xFFF );
450
467
/* Disable FMC ISP function */
451
468
FMC_Close ();
452
469
/* Lock protected registers */
453
470
SYS_LockReg ();
454
- }
471
+ }
455
472
456
473
word1 |= 0x00000200 ;
457
474
word1 &= 0x0000FEFF ;
458
475
459
- mac [0 ] = (word1 & 0x0000ff00 ) >> 8 ;
476
+ mac [0 ] = (word1 & 0x0000ff00 ) >> 8 ;
460
477
mac [1 ] = (word1 & 0x000000ff );
461
478
mac [2 ] = (word0 & 0xff000000 ) >> 24 ;
462
479
mac [3 ] = (word0 & 0x00ff0000 ) >> 16 ;
463
480
mac [4 ] = (word0 & 0x0000ff00 ) >> 8 ;
464
481
mac [5 ] = (word0 & 0x000000ff );
465
-
466
- NU_DEBUGF (("mac address %02x-%02x-%02x-%02x-%02x-%02x \r\n" , mac [0 ], mac [1 ],mac [2 ],mac [3 ],mac [4 ],mac [5 ]));
482
+
483
+ NU_DEBUGF (("mac address %02x-%02x-%02x-%02x-%02x-%02x \r\n" , mac [0 ], mac [1 ], mac [2 ], mac [3 ], mac [4 ], mac [5 ]));
467
484
}
468
485
469
- void numaker_eth_enable_interrupts (void ) {
486
+ void numaker_eth_enable_interrupts (void )
487
+ {
470
488
EMAC -> INTEN |= EMAC_INTEN_RXIEN_Msk |
471
489
EMAC_INTEN_TXIEN_Msk ;
472
- NVIC_EnableIRQ (EMAC_RX_IRQn );
473
- NVIC_EnableIRQ (EMAC_TX_IRQn );
490
+ NVIC_EnableIRQ (EMAC_RX_IRQn );
491
+ NVIC_EnableIRQ (EMAC_TX_IRQn );
474
492
}
475
493
476
- void numaker_eth_disable_interrupts (void ) {
477
- NVIC_DisableIRQ (EMAC_RX_IRQn );
478
- NVIC_DisableIRQ (EMAC_TX_IRQn );
494
+ void numaker_eth_disable_interrupts (void )
495
+ {
496
+ NVIC_DisableIRQ (EMAC_RX_IRQn );
497
+ NVIC_DisableIRQ (EMAC_TX_IRQn );
479
498
}
0 commit comments