No Transmission on SAMV71

Almost a duplicate of Tom Walsh post on the transmission issue with SAME70. For my project we are using a Atmel SAMV71 Xplain Ultra and FreeRTOS + TCP. As a base we chose the board specific examples provided by Atmel studio and upgraded the FreeRTOS version to 10 (8x as default i think). We can see incoming messages being sent over the link in the embedded debugger and that we try to respond or send packages of our own (DHCP etc), but we cannot pick up any outgoing messages with wireshark or from the router logs. Hence we get no IP address to the board and are somewhat stuck in our project. Same issue arises from other examples like LWIP — we can see no errors from the debbuger, it states that its DHCP but times out and sets static ip — none are shown in wireshark or picked up by router logs. As students with little debbuging experience we are unsure where to even look for the faults — concerning as well as the examples states that they are plug-and-play(lack for better woring) and good starting plattforms for projects. Software FreeRTOS FreeRTOS PLus TCP network driver recommended on avrfreaks forum: (We have tested with the default also) https://github.com/jtbr/FreeRTOS-TCPSAMV71NetIntf/blob/master/NetworkInterface.c “Log” from the embedded debugger ~~~ — Freertos Example — — SAMV71-XLTRA — ATSAMV71Q21B — Compiled: Feb 23 2018 11:00:19 — Network buffer initialized. Determine the first anonymous TCP port number to get assigned. prvIPTask started GMACInit started… xGMACWaitLS: 1 (PHY 1) periph freq 150 Mhz Network buffers: 60 lowest 60 Polling RX-Event… pxGetNetworkBufferWithDescriptor. Network buffers: 59 lowest 59 prvInitialiseDHCP: start after 250 ticks pxGetNetworkBufferWithDescriptor. vDHCPProcess: discover gmacstarttransmission called. Packet is sent to the network. pxGetNetworkBufferWithDescriptor. vDHCPProcess: discover vDHCPProcess: timeout 10000 ticks gmacstarttransmission called. Packet is sent to the network. pxGetNetworkBufferWithDescriptor. vDHCPProcess: discover vDHCPProcess: timeout 20000 ticks gmacstarttransmission called. Packet is sent to the network. pxGetNetworkBufferWithDescriptor. vDHCPProcess: discover vDHCPProcess: timeout 40000 ticks gmacstarttransmission called. Packet is sent to the network. pxGetNetworkBufferWithDescriptor. vDHCPProcess: discover vDHCPProcess: timeout 80000 ticks gmacstarttransmission called. Packet is sent tNetwork buffers: 58 lowest 58 o the network. Network buffers: 59 lowest 58 vDHCPProcess: giving up 160000 > 120000 ticks Network UP. Machine info: IP Address = 192.168.0.9 MAC Address = FC C2 3D 12 1B 82 pxGetNetworkBufferWithDescriptor. Generating ARP request. gmacstarttransmission called. Packet is sent to the network. pxGetNetworkBufferWithDescriptor. Generating ARP request. gmacstarttransmission called. Packet is sent to the network. pxGetNetworkBufferWithDescriptor. Generating ARP request. Returning GMACTXBUSY Unsuccessful packet send pxGetNetworkBufferWithDescriptor. Generating ARP request. Returning GMACTXBUSY Unsuccessful packet send ~~~ Any hits/help is very welcome Thanks for your time Regards, Robert & Karl

No Transmission on SAMV71

[reserving this spot if i need to upload any code or other relevant information]

No Transmission on SAMV71

Hi Robert, Karl, what we found earlier is that the GMAC of a SAME70 has 3 priority queues. Even if you only use one priority queue, the others must be set-up to point to a valid DMA descriptor. For SAME70, we added the following: ~~~

if( SAME70 != 0 )

COMPILER_ALIGNED(8)
static gmac_tx_descriptor_t gs_tx_desc_null;

endif

~~~ and later on: ~~~ #if( SAME70 != 0 ) { gmacsettxpriorityqueue(phw, (uint32t)&gstxdescnull, GMACQUE1); gmacsettxpriorityqueue(phw, (uint32t)&gstxdescnull, GMACQUE2); } ~~~ The SAM V7 has more than 3 priority queues, and they probably must all be set to point to an empty descriptor. DHCP and testing: I would recommend to switch off DHCP and supply a fixed IP-address. The stack will send so-called gratuitous ARP packets every 20 seconds: ~~~ #define arpGRATUITOUSARPPERIOD ( pdMSTOTICKS( 20000 ) ) ~~~ ARP packets should arrive on every node ( laptop ) on a LAN and can be seen in Wireshark. You can easily filter ARP packets with the word “arp”. How about memory caching? Remember that DMA has direct access to the memories, it works beyond the caching system. So just before starting a transmission, the memories invoved should be flushed. Or, an easier solution while testing: switch off all memory caching for all RAM(s). Please keep us up-to-date about your progress, I’m very curious. Thanks!

No Transmission on SAMV71

Thanks for the reply Hein! With the suggested changes we can set a static IP and the traffic is visiable on wireshark. However the router does not recognize the device, as it would with lets say a Raspberri or other computer(I.e showns as a “connected device” in the router admin panel). But when we can ping the device with normal respons and all traffic looks good. DHCP still does not work — we get a offer of an IP from the router but something happens with the package that we are uncertain of — but we think it has somerthing to do with the FreeRTOS_recfrom function, it always return 0 or -11. A big step in the right direction anyways 🙂 Thanks again! ~~~ /———————————————————–/ /* * FreeRTOSrecvfrom: receive data from a bound socket * In this library, the function can only be used with connectionsless sockets * (UDP) */ int32t FreeRTOSrecvfrom( Sockett xSocket, void pvBuffer, size_t xBufferLength, BaseType_t xFlags, struct freertos_sockaddr *pxSourceAddress, socklen_t *pxSourceAddressLength ) { BaseType_t lPacketCount = 0; NetworkBufferDescriptor_t *pxNetworkBuffer; FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * ) xSocket; TickType_t xRemainingTime = ( TickType_t ) 0; / Obsolete assignment, but some compilers output a warning if its not done. */ BaseType_t xTimed = pdFALSE; TimeOut_t xTimeOut; int32_t lReturn; EventBits_t xEventBits = ( EventBits_t ) 0;
if( prvValidSocket( pxSocket, FREERTOS_IPPROTO_UDP, pdTRUE ) == pdFALSE )
{
    return -pdFREERTOS_ERRNO_EINVAL;
}

lPacketCount = ( BaseType_t ) listCURRENT_LIST_LENGTH( &( pxSocket->u.xUDP.xWaitingPacketsList ) );

/* The function prototype is designed to maintain the expected Berkeley
sockets standard, but this implementation does not use all the parameters. */
( void ) pxSourceAddressLength;

while( lPacketCount == 0 )
{
    if( xTimed == pdFALSE )
    {
        /* Check to see if the socket is non blocking on the first
        iteration.  */
        xRemainingTime = pxSocket->xReceiveBlockTime;

        if( xRemainingTime == ( TickType_t ) 0 )
        {
            #if( ipconfigSUPPORT_SIGNALS != 0 )
            {
                /* Just check for the interrupt flag. */
                xEventBits = xEventGroupWaitBits( pxSocket->xEventGroup, eSOCKET_INTR,
                    pdTRUE /*xClearOnExit*/, pdFALSE /*xWaitAllBits*/, socketDONT_BLOCK );
            }
            #endif /* ipconfigSUPPORT_SIGNALS */
            break;
        }

        if( ( xFlags & FREERTOS_MSG_DONTWAIT ) != 0 )
        {
            break;
        }

        /* To ensure this part only executes once. */
        xTimed = pdTRUE;

        /* Fetch the current time. */
        vTaskSetTimeOutState( &xTimeOut );
    }

    /* Wait for arrival of data.  While waiting, the IP-task may set the
    'eSOCKET_RECEIVE' bit in 'xEventGroup', if it receives data for this
    socket, thus unblocking this API call. */
    xEventBits = xEventGroupWaitBits( pxSocket->xEventGroup, eSOCKET_RECEIVE | eSOCKET_INTR,
        pdTRUE /*xClearOnExit*/, pdFALSE /*xWaitAllBits*/, xRemainingTime );

    #if( ipconfigSUPPORT_SIGNALS != 0 )
    {
        if( ( xEventBits & eSOCKET_INTR ) != 0 )
        {
            if( ( xEventBits & eSOCKET_RECEIVE ) != 0 )
            {
                /* Shouldn't have cleared the eSOCKET_RECEIVE flag. */
                xEventGroupSetBits( pxSocket->xEventGroup, eSOCKET_RECEIVE );
            }
            break;
        }
    }
    #else
    {
        ( void ) xEventBits;
    }
    #endif /* ipconfigSUPPORT_SIGNALS */

    lPacketCount = ( BaseType_t ) listCURRENT_LIST_LENGTH( &( pxSocket->u.xUDP.xWaitingPacketsList ) );

    if( lPacketCount != 0 )
    {
        break;
    }

    /* Has the timeout been reached ? */
    if( xTaskCheckForTimeOut( &xTimeOut, &xRemainingTime ) )
    {
        break;
    }
} /* while( lPacketCount == 0 ) */

if( lPacketCount != 0 )
{
    taskENTER_CRITICAL();
    {
        /* The owner of the list item is the network buffer. */
        pxNetworkBuffer = ( NetworkBufferDescriptor_t * ) listGET_OWNER_OF_HEAD_ENTRY( &( pxSocket->u.xUDP.xWaitingPacketsList ) );

        if( ( xFlags & FREERTOS_MSG_PEEK ) == 0 )
        {
            /* Remove the network buffer from the list of buffers waiting to
            be processed by the socket. */
            uxListRemove( &( pxNetworkBuffer->xBufferListItem ) );
        }
    }
    taskEXIT_CRITICAL();

    /* The returned value is the data length, which may have been capped to
    the receive buffer size. */
    lReturn = ( int32_t ) pxNetworkBuffer->xDataLength;

    if( pxSourceAddress != NULL )
    {
        pxSourceAddress->sin_port = pxNetworkBuffer->usPort;
        pxSourceAddress->sin_addr = pxNetworkBuffer->ulIPAddress;
    }

    if( ( xFlags & FREERTOS_ZERO_COPY ) == 0 )
    {
        /* The zero copy flag is not set.  Truncate the length if it won't
        fit in the provided buffer. */
        if( lReturn > ( int32_t ) xBufferLength )
        {
            iptraceRECVFROM_DISCARDING_BYTES( ( xBufferLength - lReturn ) );
            lReturn = ( int32_t )xBufferLength;
        }

        /* Copy the received data into the provided buffer, then release the
        network buffer. */
        memcpy( pvBuffer, ( void * ) &( pxNetworkBuffer->pucEthernetBuffer[ ipUDP_PAYLOAD_OFFSET_IPv4 ] ), ( size_t )lReturn );

        if( ( xFlags & FREERTOS_MSG_PEEK ) == 0 )
        {
            vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
        }
    }
    else
    {
        /* The zero copy flag was set.  pvBuffer is not a buffer into which
        the received data can be copied, but a pointer that must be set to
        point to the buffer in which the received data has already been
        placed. */
        *( ( void** ) pvBuffer ) = ( void * ) ( &( pxNetworkBuffer->pucEthernetBuffer[ ipUDP_PAYLOAD_OFFSET_IPv4 ] ) );
    }

}

if( ipconfigSUPPORT_SIGNALS != 0 )

else if( ( xEventBits & eSOCKET_INTR ) != 0 )
{
    lReturn = -pdFREERTOS_ERRNO_EINTR;
    iptraceRECVFROM_INTERRUPTED();
}

endif /* ipconfigSUPPORT_SIGNALS */

else
{
    lReturn = -pdFREERTOS_ERRNO_EWOULDBLOCK;
    iptraceRECVFROM_TIMEOUT();
}

return lReturn;
} ~~~

No Transmission on SAMV71

Update: Setting FreeRTOSZEROCOPY to 0 made DHCP work and we are visiable in the router admin panel as a connected device. looks good! We do how ever not respond to future ARP request (router asking who has xxx ip — our ip address). Looking into this now.

No Transmission on SAMV71

We do how ever not respond to future ARP request (router asking who has xxx ip — our ip address).
Isn’t that the so-called gratuitous ARP-request that your are seeing? It comes from your device every 20 seconds. That ARP request is actually a question like: “does any device happen to have the same IP-address as I have?” Can you ping you device now? Ping also uses one ARP request to find the MAC-address of your device