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