This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TMS320F28388D: Does EMAC link speed affect time between TX and RX in loopback mode?

Part Number: TMS320F28388D
Other Parts Discussed in Thread: C2000WARE

In the long run I would like to establish an Ethernet point to point connection between two F28388D for sending and receiving very short packets with minimal latency. I don't need any fancy buffer handling or packet filtering or even address information. Just the raw data and a checksum would suffice.

In order to investigate how fast I can send packets over Ethernet I have created a System Project as a blend of example projects from C2000ware 4.02:

From ethernet_ipc_ex1_basic_c28x1 I have taken the IPC part and integrated it into interrupt_ex4_epwm_realtime_interrupt such that the EPWM ISR modifies some packet data and sends an IPC message signalling the CM that the data is ready to be transmitted:

    if (EPwm1TimerIntCount % 10 == 0) {
        *((uint32_t *)packetData + 2) = EPwm1TimerIntCount;

        GPIO_writePin(0,1);  // PIN 49
        IPC_sendCommand(IPC_CPU1_L_CM_R, IPC_FLAG0, IPC_ADDR_CORRECTION_ENABLE,
                        IPC_CMD_READ_MEM, (uint32_t)packetData, PACKET_LENGTH);

        GPIO_writePin(0,0);  // 700 ns
        //
        // Wait for acknowledgment
        //
        GPIO_writePin(1,1); // PIN 50
        IPC_waitForAck(IPC_CPU1_L_CM_R, IPC_FLAG0);
        GPIO_writePin(1,0);  // 2.3 us after rising edge on GPIO 0
    }

The CM side part of the project is based on ethernet_ipc_ex1_basic_cm. The EMAC is configured for loopback mode. In the IPC ISR the packet (that is located in MSGRAM) ist transmitted:

void IPC_ISR0()
{
    uint32_t command, addr, data;


    //
    // Read the command
    //
    GPIO_writePin(3,1); // PIN 55, 700 ns after rising edge of GPIO0 
    IPC_readCommand(IPC_CM_L_CPU1_R, IPC_FLAG0, IPC_ADDR_CORRECTION_ENABLE,
                    &command, &addr, &data);
    GPIO_writePin(3,0);  // 2.0 us after rising edge of GPIO0

    // Acknowledge the flag
    GPIO_writePin(4,1);  // PIN 50 2.05 us
    IPC_ackFlagRtoL(IPC_CM_L_CPU1_R, IPC_FLAG0);
    GPIO_writePin(4,0);  // 2.15 us after rising edge of GPIO0

    if(command == IPC_CMD_READ_MEM)
    {
        status = true;
        //
        //Read the buffer address and Length
        //from the IPC message
        //
        pktDesc.dataBuffer = (uint8_t *)addr;
        pktDesc.bufferLength = data;
        pktDesc.pktLength = data;
        pktDesc.validLength = data;
        //
        //Send the packet on receiving Message from C28x side
        //
        GPIO_writePin(5,1);  // PIN 52: 2.45 us after rising edge of GPIO0
        Ethernet_sendPacket(emac_handle,&pktDesc);
        GPIO_writePin(5,0); // 8.8 us after rising edge of GPIO (for packet pktLength=64)
    }
}

Finally, after packet reception myEthernet_receivePacketCallback() is called:

Ethernet_Pkt_Desc *myEthernet_receivePacketCallback(
    Ethernet_Handle handleApplication,
    Ethernet_Pkt_Desc *pPacket)
{
    Ethernet_Pkt_Desc *p;

    GPIO_writePin(6,1); // PIN 54: about 79 us after rising edge of GPIO 0 for 64 byte packets
    p = Ethernet_getPacketBuffer(); 
    GPIO_writePin(6,0); // about 80 us after rising edge of GPIO 0

    return p;
}

I have done time measurements using GPIOs and an oscilloscope. The times measured w.r.t. the call of IPC_sendCommand() are in the comments after GPIO_writePin() calls in the code snippets above.

I'm surprised that it takes about 80 us to transmit a 64 byte packet.

I have fiddled a bit with EMAC options regarding duplex and 10M/100M speed:

    Ethernet_setMACConfiguration(Ethernet_device_struct.baseAddresses.enet_base, ETHERNET_MAC_CONFIGURATION_FES); // 100 Mbps
    // Ethernet_clearMACConfiguration(Ethernet_device_struct.baseAddresses.enet_base, ETHERNET_MAC_CONFIGURATION_FES); // 10 Mbps
    // Ethernet_setMACConfiguration(Ethernet_device_struct.baseAddresses.enet_base, ETHERNET_MAC_CONFIGURATION_DM);  // Full Duplex mode
    Ethernet_clearMACConfiguration(Ethernet_device_struct.baseAddresses.enet_base, ETHERNET_MAC_CONFIGURATION_DM);  // Half Duplex mode
and I have made the following observations:

  • The EMAC speed (FES bit) appears not to have any influence on the transmission times.
  • Packet reception is delayed by another 2 us when duplex mode (DM bit) is enabled.
  • When I increase the packet size by 10 from 64 to 74 the reception is delayed by another 8 us (which looks as if there is somewhere a 10 Mbps bottleneck).

Is this to be expected? I'm afraid I have some serious mistakes in my EMAC configuration but I don't know where to look.

I would be grateful for any suggestions that help drastically reducing communication delays.

I'm willing to share my example project in case someone wants to have a closer look.

Best regards

Johannes