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.

TMS570LC4357: Regarding Issues with Emac Data Transmission and Reception on TMS570LC4357

Part Number: TMS570LC4357

Tool/software:

I am trying to transmit and receive data using emac module of TMS570LC4357 via ethernet cable , I am unable to transmit and receive data using Emac module . I am using two Dsp one for transmission and another for reception. Help me to resolve this issue. I have attached my transmission and reception code below.

#include "HL_emac.h"
#include "HL_mdio.h"
#include "HL_emac_phyConfig.h"
#include <stdio.h>
#include <stdint.h>
#include <string.h>

// Define MAC addresses
uint8_t myMac[6] = {0x00, 0x08, 0xEE, 0x03, 0xA6, 0x6C}; // DSP1 MAC address
uint8_t destMac[6] = {0x00, 0x08, 0xEE, 0x03, 0xA6, 0x6D}; // DSP2 MAC address

int main() {
    // Add 167ms delay for PHY stabilization
    volatile uint32_t delay = 167000; // Assuming 1us per loop
    while (delay--);

    // Initialize hdkif structure
    hdkif_t hdkif = {
        .mac_addr = {0x00, 0x08, 0xEE, 0x03, 0xA6, 0x6C},
        .emac_base = EMAC_0_BASE,
        .emac_ctrl_base = EMAC_CTRL_0_BASE,
        .emac_ctrl_ram = EMAC_CTRL_RAM_0_BASE,
        .mdio_base = MDIO_0_BASE,
        .phy_addr = EMAC_PHYADDRESS,
        .phy_autoneg = NULL,
        .phy_partnerability = NULL,
        .txchptr = {NULL, NULL, NULL},
        .rxchptr = {NULL, NULL, NULL}
    };

    // Initialize MDIO and EMAC
    MDIOInit(MDIO_0_BASE, MDIO_FREQ_INPUT, MDIO_FREQ_OUTPUT);
    EMACInit(EMAC_CTRL_0_BASE, EMAC_0_BASE);
    EMACInstConfig(&hdkif); // Configure instance
    EMACDMAInit(&hdkif);    // Initialize DMA

    // Set up transmit buffer
    static uint8_t txBuffer[1518]; // Ethernet MTU size

    // Construct Ethernet frame
    memcpy(txBuffer, destMac, 6); // Destination MAC
    memcpy(txBuffer + 6, myMac, 6); // Source MAC
    uint16_t etherType = 0x0800; // EtherType (e.g., IPv4)
    memcpy(txBuffer + 12, &etherType, 2); // Corrected typo
    uint8_t payload[] = "Hello from DSP1!";
    memcpy(txBuffer + 14, payload, sizeof(payload));

    // Set up pbuf structure
    pbuf_t pbuf = {
        .next = NULL,
        .payload = txBuffer,
        .tot_len = 14 + sizeof(payload),
        .len = 14 + sizeof(payload)
    };

    // Set up transmit descriptor
    static emac_tx_bd_t txDesc;
    txDesc.next = NULL;
    txDesc.bufptr = (uint32_t)txBuffer;
    txDesc.bufoff_len = (0U << 16U) | 1518 ;// Offset 0, length
    txDesc.flags_pktlen =  EMAC_BUF_DESC_SOP | EMAC_BUF_DESC_EOP | EMAC_BUF_DESC_OWNER;

    // Link descriptor to hdkif
    hdkif.txchptr.free_head = &txDesc;

    // Start transmission
    boolean result = EMACTransmit(&hdkif, &pbuf);
    if (result == EMAC_ERR_OK) {
        // Wait for transmission to complete (polling)
        while ((txDesc.flags_pktlen & EMAC_BUF_DESC_OWNER) != 0);
        printf("Transmission complete.\n");
    } else {
        printf("Transmission failed.\n");
    }

    return 0;
}

#include "HL_emac.h"
#include "HL_mdio.h"
#include "HL_emac_phyConfig.h"
#include <stdio.h>
#include <stdint.h>
#include <string.h>

// Define MAC address for DSP2
uint8_t myMac[6] = {0x00, 0x08, 0xEE, 0x03, 0xA6, 0x6C}; // DSP2 MAC address
int a=99;
int b = 99;

int main() {
    // Add 167ms delay for PHY stabilization
    volatile uint32_t delay = 167000; // Assuming 1us per loop
    while (delay--);

    // Initialize hdkif structure
    hdkif_t hdkif = {
        .mac_addr = {0x00, 0x08, 0xEE, 0x03, 0xA6, 0x6C},
        .emac_base = EMAC_0_BASE,
        .emac_ctrl_base = EMAC_CTRL_0_BASE,
        .emac_ctrl_ram = EMAC_CTRL_RAM_0_BASE,
        .mdio_base = MDIO_0_BASE,
        .phy_addr = EMAC_PHYADDRESS,
        .phy_autoneg = NULL,
        .phy_partnerability = NULL,
        .txchptr = {NULL, NULL, NULL},
        .rxchptr = {NULL, NULL, NULL}
    };

    // Initialize MDIO and EMAC
    MDIOInit(MDIO_0_BASE, MDIO_FREQ_INPUT, MDIO_FREQ_OUTPUT);
    EMACInit(EMAC_CTRL_0_BASE, EMAC_0_BASE);
    EMACInstConfig(&hdkif); // Configure instance
    EMACDMAInit(&hdkif);    // Initialize DMA

    // Enable receive interrupts for channel 0
    EMACRxIntPulseEnable(EMAC_0_BASE, EMAC_CTRL_0_BASE, EMAC_INT_CORE0_RX, EMAC_CHANNEL_0);

    // Set up receive buffer
    static uint8_t rxBuffer[1518]; // Ethernet MTU size

    // Set up receive descriptor
    static emac_rx_bd_t rxDesc;
    rxDesc.next = NULL;
    rxDesc.bufptr = (uint32_t)rxBuffer;
    rxDesc.bufoff_len = (0U << 16U) | 1518; // Offset 0, buffer length
    rxDesc.flags_pktlen = EMAC_BUF_DESC_OWNER; // Mark as owned by EMAC

    // Link descriptor to hdkif
    hdkif.rxchptr.free_head = &rxDesc;
    hdkif.rxchptr.active_head = &rxDesc;
    hdkif.rxchptr.active_tail = &rxDesc;

    // Write descriptor to hardware
    EMACRxHdrDescPtrWrite(EMAC_0_BASE, (uint32_t)&rxDesc, EMAC_CHANNEL_0);

    // Enable receiving
    EMACRxEnable(EMAC_0_BASE);

    // Poll for received packet
    printf("Waiting for packet...\n");
    a =4;
    while ((rxDesc.flags_pktlen ) != 0); // Wait until EMAC clears OWNER flag
    b =4;
    // Process received packet
    EMACReceive(&hdkif);

    // Check if packet was received
    if ((rxDesc.flags_pktlen & EMAC_BUF_DESC_SOP) && (rxDesc.flags_pktlen & EMAC_BUF_DESC_EOP)) {
        uint32_t pktLen = rxDesc.flags_pktlen & 0xFFFFU; // Extract packet length
        if (pktLen >= 14) { // Minimum header size
            // Verify source MAC (DSP1: 00:01:02:03:04:05)
            uint8_t expectedSrcMac[6] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05};
            if (memcmp(rxBuffer + 6, expectedSrcMac, 6) == 0) {
                // Verify EtherType (0x0800)
                uint16_t receivedEtherType;
                memcpy(&receivedEtherType, rxBuffer + 12, 2);
                if (receivedEtherType == 0x0800) {
                    // Extract and print payload
                    uint8_t *payload = rxBuffer + 14;
                    uint32_t payloadLen = pktLen - 14;
                    printf("Received packet from DSP1, payload: ");
                    uint32_t i;
                    for ( i = 0; i < payloadLen && i < 100; i++) { // Limit to 100 chars for safety
                        printf("%c", payload[i]);
                    }
                    printf("\n");
                } else {
                    printf("Received packet with unexpected EtherType: 0x%04X\n", receivedEtherType);
                }
            } else {
                printf("Received packet with unexpected source MAC\n");
            }
        } else {
            printf("Received packet too short: %u bytes\n", pktLen);
        }
    } else {
        printf("No valid packet received\n");
    }

    return 0;
}

  • Hi Kanak Yadav,

    Can you please refer below thread once?

    (+) RM57L843: Cannot start EMAC transmission - Arm-based microcontrollers forum - Arm-based microcontrollers - TI E2E support forums

    First i would suggest you try with disabling cache.

    And also try to run loopback example that i shown above.

    If these things working, then we can proceed with next steps.

    --
    Thanks & regards,
    Jagadish.

  • Hi Jagdish,

    I have tried your loopback example ,its working fine. Now help me out how I transmit and receive data using ethernet cable and two TMS570LC4357.

    Thanks and Regards,

    Kanak 

  • Hi Jagadish,

    I am trying to transmit and receive data using two tms570lc4357 using ethernet cable .My transmission code working fine but i am unable to receive the packet i am also attaching my transmission code help me out for the reception code.

        /** @example example_EMAC_Loopback_TxRx.c
    *  This is an example which describes the steps to create an example application which
    *  uses the HALCoGen driver to send and receive broadcast Ethernet packets in loopback mode.
    *  The EMACTransmit API is used for transmitting a single packet. Here, it is called twice, thereby transferring two packets.
    *  To see the transmitted information, the transmitted and receive buffer descriptors must be observed, which are located in the EMAC RAM.
    *  In the default configuration, the transmitted descriptors can be found at 0xFC520000 (Base address of EMAC RAM) and the receive descriptors start at 0xFC521010.
    *  One can also observe the number of packets transmitted and other such information in the EMAC network statistics registers.
    *
    *  @b Step @b 1:
    *
    *  Create a new project.
    *
    *  Navigate: -> File -> New -> Project
    *
    *  @image html example_createProject.jpg "Figure: Create a new Project"
    *
    *  @b Step @b 2:
    *
    *  Configure driver code generation:
    *  - Enable EMAC driver
    *  - Disable others
    *
    *  Navigate: -> TMS570LSxx /RM4 -> Driver Enable
    *
    *
    *  @b Step @b 3:
    *
    *  Configure Interrupt handling:
    *  - Under ‘VIM Channels 64-95’, enable EMAC Tx and Rx interrupts (Channels 77 and 79 respectively).
    *
    *  Navigate: -> TMS570LSxx /RM4 -> VIM Channels 64-95
    *
    *  @image html emac_interruptenable.jpg "Figure: Interrupt Configuration"
    *
    *  @b Step @b 4:
    *
    *  Configure PLL:
    *  - Under the ‘PLL’ tab, change the multiplier for both PLLs to a value of 150, such that the output frequency in both cases is 300.00 MHz.
    *
    *  Navigate: -> TMS570LSxx /RM4 -> PLL
    *
    *  @image html emac_PLL.jpg "Figure: PLL Configuration"
    *
    *  @b Step @b 5:
    *
    *  Configure GCM:
    *  - Under the ‘GCM’ tab, change the value of the VCLK1, VCLK2 and VCLK3 Dividers to 1 and
    *    VCLKA4 Divider to 2,  such that the output of VCLKA4_DIV is 37.50 MHz.
    *
    *  Navigate: -> TMS570LSxx /RM4 -> GCM
    *
    *  @image html emac_gcm.jpg "Figure: GCM Configuration"
    *
    *  @b Step @b 6:
    *
    *  Configure PINMUX
    *  - Under the ‘PINMUX’ tab, enable RMII/MII under pin muxing. Under 'Input Muxing', enable MDIO(G3), MII_COL(F3), MII_CRS(B4), MII_RX_DV(B11),
    *    MII_RX_ER(N19), MII_RXCLK(K19), MII_RXD[0], MII_RXD[1], MII_RXD[2], MII_RXD[3], MII_TX_CLK.
    *
    *  Navigate: -> OS -> PINMUX.
    *
    *  @image html emac_pinmux.jpg "Figure: PINMUX Configuration"
    *
    *  @b Step @b 7:
    *
    *  Configure EMAC:
    *  -change the EMAC address to any MAC Address of your choice. The physical address is 1 by default.
    *  -Enable Loopback. Leave the other options with their default values.
    *  Navigate: -> File -> EMAC
    *
    *  @image html emac_config.jpg "Figure: EMAC Configuration"
    *
    *  @b Step @b 8:
    *
    *  Generate code
    *
    *  Navigate: -> File -> Generate Code
    *
    *  @image html example_freeRTOS_generateCode.jpg "Figure: Generate Code"
    *
    *  @b Step @b 9:
    *
    *  Copy source code below into your application.
    *
    *  The example file example_EMAC_Loopback_TxRx.c can also be found in the examples folder: ../HALCoGen/examples
    *
    *  @note HALCoGen generates an empty main function in sys_main.c,
    *        please make sure that you link in the right main function or copy the source into the user code sections of this file.
    *
    */
    
    #include "HL_sys_common.h"
    #include "HL_system.h"
    
    /* USER CODE BEGIN (1) */
    #include "HL_emac.h"
    #include "HL_hw_reg_access.h"
    #include "string.h"
    /* USER CODE END */
    
    /** @fn void main(void)
    *   @brief Application main function
    *   @note This function is empty by default.
    *
    *   This function is called after startup.
    *   The user can use this function to implement the application.
    */
    //
    //uint8 emacAddress[6U] =   {0x00U, 0x08U, 0xEEU, 0x03U, 0xA6U, 0x6CU};
    //uint32    emacPhyAddress  =   1U;
    //
    ///* USER CODE BEGIN (2) */
    
    //#include "HL_emac.h"
    //#include "HL_sys_common.h"
    //#include "string.h"
    
    // MAC Address of MCU-A
    uint8 emacAddress_A[6U] = {0x00U, 0x08U, 0xEEU, 0x03U, 0xA6U, 0x6CU};
    uint32 emacPhyAddress_A = 1U;
    
    // Descriptor Data Structures
    extern hdkif_t hdkif_data[1];
    pbuf_t tx_pack[5];                     // Array for multiple packets
    uint8 tx_data[5][100];                 // Data storage for each packet
    uint32 packet_count = 5;               // Number of packets to transmit
    uint32 tx_size = 100;
    
    void create_tx_packet(uint32 index, const char *message) {
        int j;
        tx_pack[index].tot_len = tx_size;
        tx_pack[index].len = tx_size;
    
        // Destination MAC (Broadcast FF:FF:FF:FF:FF:FF)
        for(j = 0; j < 6; j++) {
            tx_data[index][j] = 0xFFU;
        }
    
        // Source MAC (MCU-A MAC Address)
        for(j = 0; j < 6; j++) {
            tx_data[index][j + 6] = emacAddress_A[j];
        }
    
        // Type/Length (0x0800 for IPv4 or any custom value)
        tx_data[index][12] = 0x08;
        tx_data[index][13] = 0x00;
    
        // Payload Data (Send the message)
        memcpy(&tx_data[index][14], message, strlen(message) + 1);  // +1 for null terminator
    
        // Assign the payload and clear the next pointer
        tx_pack[index].payload = &tx_data[index][0];
        tx_pack[index].next = NULL;
    }
    
    void main(void) {
        volatile int i;
        _enable_IRQ();
        EMACHWInit(emacAddress_A);  // Initialize EMAC
    
        // Create multiple packets
        create_tx_packet(0, "Hello Packet 1");
        create_tx_packet(1, "Hello Packet 2");
        create_tx_packet(2, "Hello Packet 3");
        create_tx_packet(3, "Hello Packet 4");
        create_tx_packet(4, "Hello Packet 5");
        int p;
        // Transmit the packets sequentially
        for ( p = 0; p < packet_count; p++) {
            EMACTransmit(&hdkif_data[0], &tx_pack[p]);
            for (i = 0; i < 5000000; i++);  // Small delay between transmissions
        }
    
        while(1) {
            // Optional: You can implement continuous transmission here if needed
        }
    }
    

    Thanks and Regards,

    Kanak.

  • Hi Kanak,

    Are you still stuck with this issue?

    I tried couple of times to implement this requirement on my end, actually it is a new requirement for us. We already have several working ethernet examples like Active web server, LwIP and ethernet bootloader etc however we never did only EMAC communication between two boards.

    I am trying from my end but not succeeded yet. I will try it again after some time due to other priority issues.

    --
    Thanks & regards,
    Jagadish.

  • Hi Jagadish,

    Yes I am still stuck with this issue.

    I have run all the ethernet example successfully but I am trying to send simple Hello using UDP protocol over ethernet .If you have any example related to this please provide me.


    Regards,

    Kanak.

  • Hi Jagadish,

    I have run your ethernet bootloader example but I have not seen any UDP library included in this. I want to implement upd protocol and send hello world to server over ethernet can you help me how to link UPD library in Project.

    Provided me steps to create new project for this.

    Regards,

    Kanak.

  • https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/412821/udp-communication-with-lwip-library
    I have seen someone is implemented this on this launchpad but I am unable to connect them and there is no link available on this thread. Can you please see this thread and provide me any help is available this protocol is important for my project.


    Thanks and Regards,

    Kanak.

  • Hi Kanak,

    e2e.ti.com/.../quote]

    Even i can't be able to access the processor wiki links given above thread, because these are all old links so not working.

    Currently we do have only ethernet bootloader example available for UDP.

    As you can see here this have UDP driver functions for connect, receive send etc.

    You can try to modify this example and can implement according to your requirement.

    --
    Thanks & regards,
    Jagadish.