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
3135MBED_ALIGN (4 ) struct eth_descriptor rx_desc [RX_DESCRIPTOR_NUM ];
3236MBED_ALIGN (4 ) struct eth_descriptor tx_desc [TX_DESCRIPTOR_NUM ];
3337
3438struct eth_descriptor volatile * cur_tx_desc_ptr , * cur_rx_desc_ptr , * fin_tx_desc_ptr ;
3539
40+ __attribute__ ((section ("EMAC_RAM" )))
3641MBED_ALIGN (4 ) uint8_t rx_buf [RX_DESCRIPTOR_NUM ][PACKET_BUFFER_SIZE ];
42+ __attribute__ ((section ("EMAC_RAM" )))
3743MBED_ALIGN (4 ) uint8_t tx_buf [TX_DESCRIPTOR_NUM ][PACKET_BUFFER_SIZE ];
3844
3945eth_callback_t nu_eth_txrx_cb = NULL ;
4046void * nu_userData = NULL ;
4147
4248extern 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.
@@ -113,6 +121,7 @@ static int reset_phy(void)
113121 return (-1 );
114122 } else {
115123 reg = mdio_read (CONFIG_PHY_ADDR , MII_LPA );
124+ phyLPAval = reg ;
116125
117126 if (reg & ADVERTISE_100FULL ) {
118127 NU_DEBUGF (("100 full\n" ));
@@ -164,7 +173,7 @@ static void init_rx_desc(void)
164173 rx_desc [i ].status1 = OWNERSHIP_EMAC ;
165174 rx_desc [i ].buf = & rx_buf [i ][0 ];
166175 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 ) ];
168177 }
169178 EMAC -> RXDSA = (unsigned int )& rx_desc [0 ];
170179 return ;
@@ -188,10 +197,14 @@ void numaker_set_mac_addr(uint8_t *addr)
188197
189198static void __eth_clk_pin_init ()
190199{
200+ /* Unlock protected registers */
201+ SYS_UnlockReg ();
191202 /* Enable IP clock */
192203 CLK_EnableModuleClock (EMAC_MODULE );
193204 // Configure MDC clock rate to HCLK / (127 + 1) = 656 kHz if system is running at 84 MHz
194205 CLK_SetModuleClock (EMAC_MODULE , 0 , CLK_CLKDIV3_EMAC (127 ));
206+ /* Update System Core Clock */
207+ SystemCoreClockUpdate ();
195208 /*---------------------------------------------------------------------------------------------------------*/
196209 /* Init I/O Multi-function */
197210 /*---------------------------------------------------------------------------------------------------------*/
@@ -216,6 +229,8 @@ static void __eth_clk_pin_init()
216229 SYS -> GPB_MFPH &= ~(SYS_GPB_MFPH_PB14MFP_Msk | SYS_GPB_MFPH_PB15MFP_Msk );
217230 SYS -> GPB_MFPH |= SYS_GPB_MFPH_PB14MFP_EMAC_MII_MDC | SYS_GPB_MFPH_PB15MFP_EMAC_MII_MDIO ;
218231
232+ /* Lock protected registers */
233+ SYS_LockReg ();
219234}
220235
221236void numaker_eth_init (uint8_t * mac_addr )
@@ -225,15 +240,13 @@ void numaker_eth_init(uint8_t *mac_addr)
225240
226241 // Reset MAC
227242 EMAC -> CTL = EMAC_CTL_RST_Msk ;
243+ while (EMAC -> CTL & EMAC_CTL_RST_Msk ) {}
228244
229245 init_tx_desc ();
230246 init_rx_desc ();
231247
232248 numaker_set_mac_addr (mac_addr ); // need to reconfigure hardware address 'cos we just RESET emc...
233249
234- /* Limit the max receive frame length to 1514 + 4 */
235- EMAC -> MRFL = NU_ETH_MAX_FLEN ;
236- reset_phy ();
237250
238251 EMAC -> CTL |= EMAC_CTL_STRIPCRC_Msk | EMAC_CTL_RXON_Msk | EMAC_CTL_TXON_Msk | EMAC_CTL_RMIIEN_Msk | EMAC_CTL_RMIIRXCTL_Msk ;
239252 EMAC -> INTEN |= EMAC_INTEN_RXIEN_Msk |
@@ -244,7 +257,36 @@ void numaker_eth_init(uint8_t *mac_addr)
244257 EMAC_INTEN_TXABTIEN_Msk |
245258 EMAC_INTEN_TXCPIEN_Msk |
246259 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+
248290}
249291
250292
@@ -259,20 +301,22 @@ unsigned int m_status;
259301
260302void EMAC_RX_IRQHandler (void )
261303{
262- // NU_DEBUGF(("%s ... nu_eth_txrx_cb=0x%x\r\n", __FUNCTION__, nu_eth_txrx_cb));
263304 m_status = EMAC -> INTSTS & 0xFFFF ;
264305 EMAC -> INTSTS = m_status ;
265306 if (m_status & EMAC_INTSTS_RXBEIF_Msk ) {
266307 // 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 ;
269311 }
312+ EMAC_DISABLE_INT (EMAC , (EMAC_INTEN_RDUIEN_Msk | EMAC_INTEN_RXGDIEN_Msk ));
270313 if (nu_eth_txrx_cb != NULL ) nu_eth_txrx_cb ('R' , nu_userData );
271314}
272315
273316
274317void numaker_eth_trigger_rx (void )
275318{
319+ EMAC_ENABLE_INT (EMAC , (EMAC_INTEN_RDUIEN_Msk | EMAC_INTEN_RXGDIEN_Msk ));
276320 ETH_TRIGGER_RX ();
277321}
278322
@@ -291,6 +335,12 @@ int numaker_eth_get_rx_buf(uint16_t *len, uint8_t **buf)
291335 if (status & RXFD_RXGD ) {
292336 * buf = cur_rx_desc_ptr -> buf ;
293337 * 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 ));
294344 }
295345 return 0 ;
296346}
@@ -309,6 +359,8 @@ void EMAC_TX_IRQHandler(void)
309359 EMAC -> INTSTS = status ;
310360 if (status & EMAC_INTSTS_TXBEIF_Msk ) {
311361 // 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 );
312364 return ;
313365 }
314366
0 commit comments