FreeRTOS+TCP on SAME70 with ASF4 (Atmel Start) MAC drivers

Thanks for confirming Hein.

I’ve now got +TCP incorporated into my ASF project, but I’m not able to get the GMAC operational (xPhyDiscover in phyHandling isn’t finding any connected PHYs). Am I correct in my understanding that I shouldn’t be using any of ethernet files added by ASF (gmac.h, gmac_phy.h, ethernet_phy.[ch], etc.)? Having gone through them, the functionality indeed seems to be covered by the phyHandling and gmac_SAM files.

I have an ASF project which uses lwIP that works with the aforementioned ASF ethernet files, so I’m trying to determine why the PHY initialisation works in that project but not in this +TCP one. I’ve added the PHY pin configurations to the init.c board_init() function, and everything compiles without issue, it’s just &ulLowerID always returns 65535 from pxPhyObject->fnPhyRead() of register phyREG_03_PHYSID2. Note that I’ve changed the xPhyDiscover(&xPhyObject); call in prvGMACInit() to while(xPhyDiscover(&xPhyObject) < 1); to account for the PHY not being ready in time.

Am I correct in my understanding that I shouldn’t
be using any of ethernet files added by ASF

Your understanding is correct.

For xPHY_Read() and xPHY_Write() to work properly, it is necessary to:

  • have all relevant clocks initialised and enabled
  • have the EMAC set-up
  • all GPIO’s set correctly ( peripheral functions )
  • make the choice between MII or RMII :
#if( SAME70 != 0 )
{
    /* Selecting RMII mode. */
    GMAC->GMAC_UR &= ~GMAC_UR_RMII;
}
#else
{
    gmac_select_mii_mode(GMAC, ETH_PHY_MODE);
}
#endif

Thanks for that Hein. I’ve enabled the GMAC peripheral clock before calling prvGMACInit(), and have the GPIOs set in the board_init() function. With the other two points mentioned, does the order of the EMAC and R/MII setup then need to be changed in NetworkInterface, as they’re currently being called after xPhyDiscover:

    /* Set MDC clock divider. */
	gmac_set_mdc_clock( GMAC, sysclk_get_cpu_hz() );

	vPhyInitialise( &xPhyObject, xPHY_Read, xPHY_Write );
	xPhyDiscover( &xPhyObject );
	xPhyConfigure( &xPhyObject, &xPHYProperties );

	/* For a reset / reconfigure of the EMAC. */
	prvEthernetUpdateConfig( pdTRUE );

	/* Select Media Independent Interface type */
	#if( SAME70 != 0 )
	{
		/* Selecting RMII mode. */
		GMAC->GMAC_UR &= ~GMAC_UR_RMII;
	}
	#else
	{
		gmac_select_mii_mode(GMAC, ETH_PHY_MODE);
	}
	#endif

	gmac_enable_transmit(GMAC, true);
	gmac_enable_receive(GMAC, true);

I also found that gmac_set_mdc_clock uses sysclk_get_cpu_hz() which is 300MHz, greater than the allowed 240MHz maximum. I’ve changed this to sysclk_get_peripheral_hz() in my version.

Hello all,

i’m also currently trying to get a SAM E70 XPLAINED working with FreeRTOS+TCP, but have only succeeded halfway.
By using Hein’s newer driver and making the following changes (and also including Hein’s tcp_loopback.c), I can get it to detect the PHY and also successfully Auto-Negotiate the line:

--- ../../../../../DriverSAM_plus_tcp_driver/DriverSAM/gmac_SAM.c       2018-11-20 14:42:52.734487400 +0100
+++ gmac_SAM.c  2020-04-25 04:00:19.260207100 +0200
@@ -641,7 +641,7 @@
        return GMAC_OK;
 }

-extern void vGMACGenerateChecksum( uint8_t *apBuffer );
+extern void vGMACGenerateChecksum( uint8_t *apBuffer, size_t uxLength );

 /**
  * \brief Send ulLength bytes from pcFrom. This copies the buffer to one of the
@@ -693,7 +693,7 @@
                        memcpy((void *)p_tx_td->addr, p_buffer, ul_size);
                }
                #endif /* ipconfigZERO_COPY_TX_DRIVER */
-               vGMACGenerateChecksum( ( uint8_t * ) p_tx_td->addr );
+               vGMACGenerateChecksum( ( uint8_t * ) p_tx_td->addr, (size_t) ul_size );
        }

        //#warning Trying out
--- ../../../../../DriverSAM_plus_tcp_driver/DriverSAM/NetworkInterface.c       2020-04-16 11:15:05.652064400 +0200
+++ NetworkInterface.c  2020-04-25 03:59:48.648812100 +0200
@@ -81,9 +81,11 @@
 #include <sysclk.h>
 #include "phyhandling.h"

+#include "pio.h"
 /* This file is included to see if 'CONF_BOARD_ENABLE_CACHE' is defined. */
 #include "conf_board.h"

+extern BaseType_t xCheckLoopback( NetworkBufferDescriptor_t * const, BaseType_t );

 /* Interrupt events to process.  Currently only the Rx event is processed
 although code for other events is included to allow for possible future
@@ -173,7 +175,7 @@
 static BaseType_t xPHY_Write( BaseType_t xAddress, BaseType_t xRegister, uint32_t ulValue );

 #if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM == 1 ) && ( ipconfigHAS_TX_CRC_OFFLOADING == 0 )
-       void vGMACGenerateChecksum( uint8_t *apBuffer );
+       void vGMACGenerateChecksum( uint8_t *apBuffer, size_t uxLength );
 #endif

 /*
@@ -587,16 +589,6 @@
        NVIC_EnableIRQ( GMAC_IRQn );

        {
-               /* Set MDC clock divider. */
-               gmac_set_mdc_clock( GMAC, sysclk_get_cpu_hz() );
-
-               vPhyInitialise( &xPhyObject, xPHY_Read, xPHY_Write );
-               xPhyDiscover( &xPhyObject );
-               xPhyConfigure( &xPhyObject, &xPHYProperties );
-
-               /* For a reset / reconfigure of the EMAC. */
-               prvEthernetUpdateConfig( pdTRUE );
-
                /* Select Media Independent Interface type */
                #if( SAME70 != 0 )
                {
@@ -608,6 +600,20 @@
                        gmac_select_mii_mode(GMAC, ETH_PHY_MODE);
                }
                #endif
+
+               pio_set_output(PIN_GMAC_RESET_PIO, PIN_GMAC_RESET_MASK, 1,  false, true);
+               pio_set_input(PIN_GMAC_INT_PIO, PIN_GMAC_INT_MASK, PIO_PULLUP);
+               pio_set_peripheral(PIN_GMAC_PIO, PIN_GMAC_PERIPH, PIN_GMAC_MASK);
+
+               /* For a reset / reconfigure of the EMAC. */
+               prvEthernetUpdateConfig( pdTRUE );
+
+               /* Set MDC clock divider. */
+               gmac_set_mdc_clock( GMAC, sysclk_get_peripheral_hz() );
+
+               vPhyInitialise( &xPhyObject, xPHY_Read, xPHY_Write );
+               xPhyDiscover( &xPhyObject );
+               xPhyConfigure( &xPhyObject, &xPHYProperties );

                gmac_enable_transmit(GMAC, true);
                gmac_enable_receive(GMAC, true);
@@ -711,7 +717,7 @@

 //#if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM == 1 ) && ( ipconfigHAS_TX_CRC_OFFLOADING == 0 )

-       void vGMACGenerateChecksum( uint8_t *apBuffer )
+       void vGMACGenerateChecksum( uint8_t *apBuffer, size_t uxLength )
        {
        ProtocolPacket_t *xProtPacket = (ProtocolPacket_t *)apBuffer;

@@ -725,7 +731,7 @@
                        pxIPHeader->usHeaderChecksum = ~FreeRTOS_htons( pxIPHeader->usHeaderChecksum );

                        /* Calculate the TCP checksum for an outgoing packet. */
-                       usGenerateProtocolChecksum( ( uint8_t * ) apBuffer, pdTRUE );
+                       usGenerateProtocolChecksum( ( uint8_t * ) apBuffer, apLength, pdTRUE );
                }
        }

But apart from that, nothing works, neither sending nor receiving data. I watched the network with wireshark and can see absolutely nothing from the SAM.

Fun fact: I was at that exact point before with Hein’s old driver from Sourceforge.

@jars121 opened a new post, specifically about SAME70:
https://forums.freertos.org/t/freertos-tcp-on-same70

I just responded there and posted my configuration files. Hope it helps.