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

heinbali01 wrote on Thursday, November 08, 2018:

Hi Sofian,

Thanks man, good work!

On 11/8/2018 01:02, Sofian Jafar wrote:

The links:
ASF3: SAME70-Xplained-FreeRTOS+TCP_ASF3.zip - Google Drive
ASF4: SAME70-Xplained-FreeRTOS+TCP_ASF4.zip - Google Drive

I will try to keep the links as long as possible. I have also attached the files.

Do you have experience with github.com ? Do you have an account?

That is a nice way of sharing software with the public.

github.com is without charge, unless you want to have private repositories.

skjafar wrote on Thursday, November 08, 2018:

Actually I use git regularly, but I thought some people might not be as familiar, that is why I have attached them as zip files.

It’s a good suggestion, I will add them soon to my GitHub repo and post back.

mikeraw wrote on Friday, December 21, 2018:

Hi, I ran the ASF4 files, and that works. Impressive!

But I saw that the project was build on FreeRTOS version 9, not the newest version 10. Any plan to change this? They use two different lisenses, so I am a little afraid to mix between them. Should I downgrade my entire project to version 9? Thinking…

By the way, I think the D-cache “problem” should be solved by using TCM. I believe it is just a matter of adding the proper attribute to all memory shared by interrupts and tasks. I have the TCM working with DMA etc. Works perfectly. Furthermore. all interrupt code should also have the attribute for TCM set, as it will make it faster. The entire FreeRTOS and TCP stack would benefit by running from the TCM.

rtel wrote on Friday, December 21, 2018:

It would be nice if the FreeRTOS version in ASF was updated, but the ASF
is not distributed by us.

eduardo-petards wrote on Wednesday, March 27, 2019:

I have tried to generate an executable using the SAME70-Xplained-FreeRTOS+TCP_ASF4.zip file using Eclipse.
In my attempt however to create a project I have found that the file sam.h, and the others that this file includes, are not present. There are several c files that include sam.h
The problem was solved by having these files copied from a FreeRTOS distribution.
Ids it possible that project that you have created has a link to a directory outside your project?

I’m also facing another regarding the definition of Gmac in NetworkInterface.c (line 255).
typedef struct gmac_device {
/** Pointer to HW register base */
Gmac *p_hw;

I cannot find the file that defines Gmac! Any ideas about this?

eduardo-petards wrote on Wednesday, March 27, 2019:

I found gmac.h in fact 2 of them… one full of defines in instance and another with IOs and defines in component.
They are both included by same70q21.h which also includes many files in component and in instance.
I was seeing the file SAME70-Xplained-FreeRTOS+TCP_ASF4.zip has a complete solution but it seems to be dependable of an instalation of FreeRTOS and ASF.
Would this be the case?

heinbali01 wrote on Friday, March 29, 2019:

Hi Eduardo, I also get lost here. Hopefully there are other users who can shed some light on this.

I know about the 2 occurrences of gmac.h : one is a description of registers and hardware, the other contains prototypes of functions and variables.

I published a driver that is compatible with SAME70 as well as SAM4E here
Maybe that works better for you.
Whait I did is take a copy of gmac.c, change it to my wishes, and called it gmac_SAM.c, c.q.
gmac_SAM.h. But when you compile that interface, you may well get stuck on compilation errors because the version of your frame doesn’t fit. Sigh…

The problem is that the Atmel Framework changes more quickly that we have the time to adapt the existing +TCP drivers.

eduardo-petards wrote on Monday, April 01, 2019:

There is also the matter of the definition of SAME70

In parts.h is defined as:
define SAME70 (SAME70J || SAME70N || SAME70Q || SAME70JB || SAME70NB || SAME70QB)

In FreeRTOSIPConfig.h is defined as:
define SAME70 1

jarni wrote on Sunday, June 30, 2019:

On NetworkInterface.c, in prvGMACInit function, I had to do this modification:

		//xPhyDiscover( &xPhyObject );
        while(xPhyDiscover( &xPhyObject ) < 1);

since sometimes the PHY is not ready and xPhyDiscover fails and is never called again.

jarni wrote on Sunday, June 30, 2019:

And I’m working on SAME70Q21B, it seems working well.

Sorry for the thread revival; any chance the SAME70 drivers are still available? I’m unable to access the previous SourceForge links.

I’m looking to get +TCP working in the Atmel Studio FreeRTOS 10.0.0 example application with the ATSAME70Q21.

Thanks!

No problem to revive an old thread.

You can find all FreeRTOS+TCP drivers on Github here.

But… the driver for SAME70 is not there, only an old driver called ‘ATSAM4E’.

Here’s a copy of the driver that you probably found on SourceForge:

SAME70_plus_tcp_driver.zip (54.4 KB)

And here is the latest driver, that should work for both SAM4E and SAME70:

DriverSAM_plus_tcp_driver.zip (24.2 KB)

I recommend using the last driver because it is the newest. Please report how it goes.

I will prepare a pull request so it will be added to the repository on Github.

Brilliant, thanks Hein, much appreciated.

I’ll certainly report back.

Hi Hein,

I’ve got the SAME70 main_blinky program working with 10.3.0. I’m now adding +TCP and have come across a few minor issues. I’m happy to capture these on Github or elsewhere if that’s preferred.

  1. I needed to add the xCheckLoopback prototype and function to the FreeRTOS_ARP.[ch] files per this post on SourceForge. With xCheckLoopback successfully incorporated into FreeRTOS_ARP.[ch], I’ve now removed tcp_loopback.c from the project.

  2. The provided NetworkInterface.c file for SAM4E/SAME70 uses a (seemingly) outdated usGenerateProtocolChecksum function. The function in NetworkInterface.c is missing the second size_t uxBufferLength parameter. The calling function vGMACGenerateChecksum is called from gmac_dev_write in the provided gmac_SAM.c driver. Am I correct in my understanding that the ul_size (length of the frame) parameter in gmac_dev_write could be passed to vGMACGenerateChecksum to be used as the uxBufferLength parameter in usGenerateProtocolChecksum? I’m not entirely sure if the ‘frame length’ is equal to the ‘buffer size’ in this case.

I’ll have a go at getting the basic TCP echo example working in the meantime.

Implementing xCheckLoopback()` is only useful if you plan to send packets to your own (MAC-) address. It was a try-out, and I never found the time to get it into mainline.

usGenerateProtocolChecksum(): sorry, yes the later implementation also wants to know the length of the packet. This call should do it.

   usGenerateProtocolChecksum( pxBuffer->pucEthernetBuffer,
                               pxBuffer->xDataLength,
                               pdTRUE );

Thanks for reporting back. I will change these two things. Hein

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.