Hi! I would like to know if the FreeRTOS+TCP Network Interface driver has been ported to the Atmel SAME5X family of microcontrollers. I assumed not, at least not officially, since I could not find anything on this in the source files.
Is there an example out there of FreeRTOS+TCP working on SAME5X, or is there a guide on how to do this?
Regards,
P.-S.: On a side note, Iâm messaging Microchip about their silicon revisions. On ALL SAM E5X 64 pins chips, silicon revision A does not have a working MAC. Stay safe, stay away from 64 pins SAM E5X chips
Thanks Richard.
The current ATSAM4E and DriverSAM ports are not very convenient to reuse, since they use old versions of Atmelâs ASF.
Iâm going to try to create a simple SAM E5X port myself, starting without the zero copy stuff. Usually being an application developer, Iâm slightly out of my depth.
It also doesnât help that I wonât be able to test beyond compiling until Microchip provides me with good silicon versions or I switch to the SAM E54.
If someone works on this, please keep me in the loop, Iâll do the same here.
Cheers,
After a few days of banging my head against the desk, I gave up porting the DriverSAM version. The ASF names and variables are a mess to translate from ASF3 to ASF4. Thatâs too much for me.
I instead followed the FreeRTOS+TCP porting guide. Luckily, Atmel / Microchip provides both MAC and PHY drivers, so implementing a simple NetworkInterface.c is simple enough.
I can not validate that this is working at this point, thanks to faulty ATSAME53 64 pins chips. I wonât be able to test until I send another board in production with the ATSAME54N20A, so thatâs probably 3 weeks delay, plus whatever Iâll be busy doing in 3 weeks.
In the meantime, I leave the code here for anyone to comment, correct and optimize.
I do however have a few questions regarding the DriverSAM port:
Why do we need to set the MDC clock divider?
Is the EMAC handler asleep by default and only called when there is an event from the GMAC? I suppose in this case we register the callback to the GMACHandler to wake up the task?
For a MQTT IoT application where I have under 30 sensors connected to this board, reporting once per minute, for this device in particular, is it worth trying to get a zero-copy driver to work? I should be pretty good at 10 mbps, and to save RAM I limit the MTU to the DHCP minimum (578?)
Here a few comments about your NetworkInterface.c :
static void prvPHYKeepAliveHandlerTask( void * pvParameters)
{
// _HT_ I recommend not to make a separate task for checking the PHY.
// Only one task should have access to the PHY (read/write).
// Also, as long as you device receives packets, you may assume that the
// PHY status is high. It can be quite disturbing if you poll the PHY
// **while receiving data**.
static void prvEMACDeferredInterruptHandlerTask( void *pvParameters )
{
// _HT_ In this task you can also check the PHY status regularly.
// Just pass a different timeout value to ulTaskNotifyTake().
BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxDescriptor,
BaseType_t xReleaseAfterSend )
{
// _HT_ I assum that you are not using a zero-copy driver?
// It does not make sense to send a packet as long as the Link Status is low
// so I would test for it:
if( phy_link_state == pdTRUE )
{
mac_async_write(ÐERNET_MAC_0, pxDescriptor->pucEthernetBuffer, pxDescriptor->xDataLength);
}
// _HT_ xNetworkInterfaceInitialise() is supposed to return pdPASS only if the EMAC is
// initialised correctly, and when the PHY Link Status is high:
BaseType_t xNetworkInterfaceInitialise( void )
{
...
return ( phy_link_state == true ) ? pdPASS : pdFAIL;
}
Answering your 3 questions:
Why do we need to set the MDC clock divider?
To get a proper clock speed for the MDIO, I think.
Is the EMAC handler asleep by default and only called when there is an event from the GMAC? I suppose in this case we register the callback to the GMACHandler to wake up the task?
Yes of cause, when an important ISR has happened, the network task should be woken up, just like you see here:
void xRxCallback( uint32_t ulStatus )
{
if( ( ( ulStatus & GMAC_RSR_REC ) != 0 ) && ( xEMACTaskHandle != NULL ) )
{
/* let the prvEMACHandlerTask know that there was an RX event. */
ulISREvents |= EMAC_IF_RX_EVENT;
/* Only an RX interrupt can wakeup prvEMACHandlerTask. */
vTaskNotifyGiveFromISR( xEMACTaskHandle, ( BaseType_t * ) &xGMACSwitchRequired );
}
}
Also I would let the task sleep for at most a second, so that the PHY link status can be checked.
For a MQTT IoT application where I have under 30 sensors connected to this board, reporting once per minute, for this device in particular, is it worth trying to get a zero-copy driver to work? I should be pretty good at 10 mbps, and to save RAM I limit the MTU to the DHCP minimum (578?)
It doesnât sound like it can be easily done, and for now you wouldnât need a zero-copy driver. The latter is useful on a fast LAN, not when communicating with a server on the Internet.
I got the NetworkInterface to kinda work with the ATSAME54N20A. I think I am facing a hardware issue, since no incoming packets are detected.
The DHCPDISCOVER packet goes out to the router, the router replies with DHCPOFFER, but GMAC_Handler() is never called. I checked the electric schematics and live signals on the scope, and everything seems fine up to pins PA12 and PA13 (RXD1 and RXD0). Interrupt register bit is properly enabled, and polling the PHY registers for errors says there are none. Does that kind of problem ring a bell?
The situation seems similar to the situation in post #8 here: ATSAME5x series Ethernet | AVR Freaks. However, since I now have a 100 pins chip, I should not have the problem⌠right?
In the meantime, here is the incomplete driver, I hope it gets someone a head start. It relies on ASF4 (Atmel start) MAC and PHY drivers and middleware. NetworkInterface.c (13.2 KB)
Edit: Yup, seems like I switched from the STM32 to the ATSAM a bit fast. I connected GCRS (PA16) to the PHYâs GCRS_DV, but Microchip decided to only connect GRX_DV (PC20) (see Table 24-1 of the datasheet). Iâll try to add a microwire and send news.
Edit 2: The mistake was made when I switched from 64 pins package to 100 pins package. In the datasheet, under Table 6-1: Multiplexed Peripheral signals, Note (6) says that GRXDV function on PA16 is only available on 64 pins devices. Oh well! (And I gave up on the microwire. Iâll be back in 2-3 weeks).
I can not see the entire driver, but I wonder if the hardware does have the MAC-address programmed, and also if it will receive packets for the broadcast address?
If you want, I will explain how to start using phyHandler.c. It is a generic PHY driver, used in many +TCP network interfaces. But that is of later care.
So in the end I started making a lot of changes to the board, so I ordered better microwire and Soldered the PHYâs CRS_DV to PC20 (took a few tries and some copper wick). After a bit of messing around, I got the DHCP to work (!!!)⌠on second try, meaning that the first DHCPOFFER is not detected, but the second one is and is followed by a DHCPREQUEST and a DHCPACK.
I will be working on this project to get the driver âgood enoughâ, with my planned test being to make it work with a mosquitto MQTT broker.
Hein, your help would be greatly appreciated to provide tips on performance, reliability and code quality, and to get me started with phyHandler.c, which I understand is preferred if I want this driver to make it to the main branch some day
Soldered the PHYâs CRS_DV to PC20 (took a few tries and some copper wick)
Youâre a brave man. I used to solder my self too, but as the years pass by, and the parts get smaller, I feel less confident.
on second try, meaning that the first DHCPOFFER is not detected
Can you describe the timing more or less? Between start-up, ask for offer, get a reply ( but not detected ), ask a second offer?
Maybe you can record some on WireShark?
Thanks, itâs a useful skill to have. Maybe some day Iâll be good enough at designing boards to not need it anymore
Can you describe the timing more or less?
I fixed it, as mentioned in the test projectâs log. I had enabled MAC frame filtering (âCopy all framesâ off), but had not configured it. The DHCPOFFER was not received in the first few seconds after boot. The dd-wrt Syslog looked like:
I am 100% positive that properly configuring the filter (and/or disabling it) fixed that issue, but I can not explain why DHCP worked at all on second try.