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.

Problem with LCDK6748 Ethernet implementation on StarterWare libs

Other Parts Discussed in Thread: AM1808

Dear community/employees

I am trying to implement LwiP stack on LCDK6748 using StarterWare 1_20_03_03 library. Unfortunately provided examples are ported for Cortex-A8 :am335x , am1808 , c6x811x only so I decided to write my own low-level hardware initialization.  I followed steps pointed in http://processors.wiki.ti.com/index.php/StarterWare_EMAC and here is my code :

 

void main()

{

PSCModuleControl(SOC_PSC_1_REGS,HW_PSC_GPIO, PSC_POWERDOMAIN_ALWAYS_ON, PSC_MDCTL_NEXT_ENABLE);

EMACPinMuxSetup();

PSCModuleControl(SOC_PSC_1_REGS,HW_PSC_EMAC, PSC_POWERDOMAIN_ALWAYS_ON, PSC_MDCTL_NEXT_ENABLE);

GPIOBank6Pin12PinMuxSetup();

GPIOBank6Pin13PinMuxSetup();

GPIOBank2Pin12PinMuxSetup();

GPIOBank0Pin9PinMuxSetup();

GPIOBank2Pin4PinMuxSetup();

GPIODirModeSet(SOC_GPIO_0_REGS, 109, GPIO_DIR_OUTPUT);

GPIODirModeSet(SOC_GPIO_0_REGS, 110, GPIO_DIR_OUTPUT);

GPIODirModeSet(SOC_GPIO_0_REGS, 45, GPIO_DIR_OUTPUT);

GPIODirModeSet(SOC_GPIO_0_REGS, 10, GPIO_DIR_OUTPUT);

GPIODirModeSet(SOC_GPIO_0_REGS, 37, GPIO_DIR_INPUT);

/* Configuration of Timer */

TimerConfigure(SOC_TMR_2_REGS, TMR_CFG_64BIT_CLK_INT);

/* Set the 64 bit timer period */

TimerPeriodSet(SOC_TMR_2_REGS, TMR_TIMER12, 0x000249F0);

TimerPeriodSet(SOC_TMR_2_REGS, TMR_TIMER34, 0);

InterruptSetup();

TimerIntEnable(SOC_TMR_2_REGS, TMR_INT_TMR12_NON_CAPT_MODE);

TimerEnable(SOC_TMR_2_REGS, TMR_TIMER12, TMR_ENABLE_CONT);

LwIP_Init();

while(1)

{

if(GPIOPinRead(SOC_GPIO_0_REGS,37))

GPIOPinWrite(SOC_GPIO_0_REGS, 10, GPIO_PIN_LOW);

else

GPIOPinWrite(SOC_GPIO_0_REGS, 10, GPIO_PIN_HIGH);

sys_check_timeouts();

}

}

void LwIP_Init()

{

//phy addr = 0x7;

ip_addr_t addr, netmask, gw;

IP4_ADDR(&addr, 192, 168, 10, 139);

IP4_ADDR(&netmask, 255, 255, 255, 0);

IP4_ADDR(&gw, 192, 168, 10, 1);

netif_add(&netif, &addr, &netmask, &gw, 0, emac_init, ethernet_input);

netif_set_default(&netif);

netif_set_up(&netif);

lwip_init();

}

err_t emac_init(struct netif *netif)

{

uint32_t i;

uint16_t partnerAbility=0;

/* LwIP network interface level */

netif->name[0] = 'e';

netif->name[1] = 't';

netif->output = etharp_output;

netif->linkoutput = emac_low_level_output;

//netif->igmp_mac_filter = c674emac_igmp_mac_filter;

netif->hwaddr[0] = MAC_Addr[0];

netif->hwaddr[1] = MAC_Addr[1];

netif->hwaddr[2] = MAC_Addr[2];

netif->hwaddr[3] = MAC_Addr[3];

netif->hwaddr[4] = MAC_Addr[4];

netif-> hwaddr[5] = MAC_Addr[5];

#if LWIP_NETIF_HOSTNAME

netif->hostname = "lwip";

#endif

netif->hwaddr_len = ETHARP_HWADDR_LEN;

netif->mtu = 1500;

netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP/*| NETIF_FLAG_IGMP*/;

EMACInit(SOC_EMAC_DSC_CTRL_MOD_REG,SOC_EMAC_DSC_CONTROL_REG);

MDIOInit(SOC_MDIO_0_REGS,phySysClk/2000,phySysClk/10);

for(i=0;i<5000;i++);//short delay

if(Lan8710aAutoNegotiate(SOC_MDIO_0_REGS,0x07,LAN8710A_100BTX_FD | LAN8710A_100BTX | LAN8710A_10BT_FD | LAN8710A_10BT) == FALSE)

return ERR_IF;

if(Lan8710aPartnerAbilityGet(SOC_MDIO_0_REGS,0x07,&partnerAbility)  == FALSE)

return ERR_IF;

EMACDuplexSet(SOC_EMAC_DSC_CONTROL_REG,EMAC_DUPLEX_FULL);

EMACMACAddrSet(SOC_EMAC_DSC_CONTROL_REG,0,MAC_Addr,EMAC_MACADDR_NO_MATCH_NO_FILTER);

EMACRxUnicastSet(SOC_EMAC_DSC_CONTROL_REG,0);

initDescriptors();

//uint32_t linkStatus = MDIOPhyLinkStatusGet(SOC_MDIO_0_REGS);

EMACTxEnable(SOC_EMAC_DSC_CONTROL_REG);

EMACRxEnable(SOC_EMAC_DSC_CONTROL_REG);

EMACRxHdrDescPtrWrite(SOC_EMAC_DSC_CONTROL_REG,EMAC_RXHDP(0),0);

EMACMIIEnable(SOC_EMAC_DSC_CONTROL_REG);

EMACTxIntPulseEnable(SOC_EMAC_DSC_CONTROL_REG,SOC_EMAC_DSC_CTRL_MOD_REG,0,0);

EMACRxIntPulseEnable(SOC_EMAC_DSC_CONTROL_REG,SOC_EMAC_DSC_CTRL_MOD_REG,0,0);

return ERR_OK;

}

void initDescriptors(void)

{

/* Prepare Descriptors */

struct cppiram_t* cppiram = (struct cppiram_t*) SOC_EMAC_DSC_CTRL_MOD_RAM;

memset(cppiram, 0, sizeof(struct cppiram_t));

uint16_t i;

for (i=0; i<TX_DESCRIPTORS; i++)

{

push_desc(&cppiram->txfree, &cppiram->txdesc[i]);

}

for (i=0; i<RX_DESCRIPTORS; i++)

{

struct pbuf* p = pbuf_alloc(PBUF_RAW, 1520, PBUF_POOL);

cppiram->rxdesc[i].pBuffer = (Uint8*) p;

cppiram->rxdesc[i].BufOffLen = 1536;

cppiram->rxdesc[i].PktFlgLen = EMAC_DSC_FLAG_OWNER | 0;

//L2CACHE_WBINV(p, 1536);

push_desc(&cppiram->rxactive, &cppiram->rxdesc[i]);

}

}

void push_desc(struct dma_queue_t* q, struct EMAC_Desc* desc)

{

desc->next = 0;

if (q->first)

q->last->next = desc;

else

q->first = desc;

q->last = desc;

q->n++;

}

return ERR_OK;

}

/*

** Timer Interrupt Service Routine

*/

static void TimerIsr(void)

{

/* Disable the timer interrupt */

    TimerIntDisable(SOC_TMR_2_REGS, TMR_INT_TMR12_NON_CAPT_MODE);

    IntEventClear(SYS_INT_T64P2_TINTALL);

    TimerIntStatusClear(SOC_TMR_2_REGS, TMR_INT_TMR12_NON_CAPT_MODE);

    totalMiliseconds++;

/* Enable the timer interrupt */

    TimerIntEnable(SOC_TMR_2_REGS, TMR_INT_TMR12_NON_CAPT_MODE);

}

u32_t sys_now(void)

{

return totalMiliseconds;

}

void InterruptSetup(void)

{

// Initialize the DSP Interrupt Controller

IntDSPINTCInit();

/* Register the Timer ISR */

IntRegister(C674X_MASK_INT6, TimerIsr);

/* Map Timer interrupts to DSP maskable interrupt */

IntEventMap(C674X_MASK_INT6, SYS_INT_T64P2_TINTALL);

/* Enable DSP interrupt in DSPINTC */

IntEnable(C674X_MASK_INT6);

// Enable DSP Interrupts Globally

IntGlobalEnable();

// Register the ISR in the Interrupt Vector Table

IntRegister(C674X_MASK_INT4, EMACCore0RxIsr);

IntRegister(C674X_MASK_INT5, EMACCore0TxIsr);

// Map the system interrupt to the DSP maskable interrupt

IntEventMap(C674X_MASK_INT4, SYS_INT_EMAC_C0RX);

IntEventMap(C674X_MASK_INT5, SYS_INT_EMAC_C0TX);

// Enable DSP maskable interrupt

IntEnable(C674X_MASK_INT4);

IntEnable(C674X_MASK_INT5);

}

void EMACCore0RxIsr(void)

{

    IntEventClear(SYS_INT_EMAC_C0RX);

}

void EMACCore0TxIsr(void)

{

    IntEventClear(SYS_INT_EMAC_C0TX);

}

 

My problem is that EMAC core interrupts aren't called after EMAC initilalization so I cannot process any incoming Ethernet packets and pass them to upper-layer Lwip function calls. Simply program counter doesn't show in either EMACCore0TxIsr or EMACCore0RxIsr. However, timer interrput and GPIOs are  working well. Could anyone tell me how to write low-level driver for C6748 EMAC ? The only ports I found are for SYS/BIOS and I need bare-matal TCP/IP stack solution.

 

  • Marcin Nowicki,

    Welcome to the TI E2E forum. TI provided examples for LCDKC6748 board in the StarterWare package.
    You can find the “lwip” sample code from StarterWare, as mentioned below path.
    C6748_StarterWare_1_20_03_03\build\c674x\cgt_ccs\c6748\lcdkC6748\enet_lwip
    C6748_StarterWare_1_20_03_03\examples\lcdkC6748\enet_lwip
    From that you can customize your own implementation for TCPIP stack.
    lwiplib.c file used in the enet_lwip project, refer the below path.
    C6748_StarterWare_1_20_03_03\third_party\lwip-1.3.2
    C6748_StarterWare_1_20_03_03\third_party\lwip-1.3.2\ports\am1808
    And also lwip-1.3.2 have document, test and app codes.

  • Thanks for immediate reply.

    I was able to import project , change linker include and libs paths,  build the project . Finally core interrupts are working well.

    However TCP/IP stack is not working yet. The packets are being received, but they have wrong destination and source MAC addresses.

    Destination MAC address is always filled with zeroes whereas source MAC address has two first bytes zeroed .

    I guess it might be connected with reading packet desciptors from CPPI RAM  in sitaraif_rx_inthandler(struct netif *netif). Maybe structs are filled wrong.

    I cannot figure out whether it is a port fault or EMAC interface configuration  fault. I'd be glad if somebody could help.

  • Marcin,

    Can you able to assign the IP address and ping the same IP?
    I suggest you, verify the EMAC through loopback of EMAC for problem identify.
    And also verify which mode you configured like MII, SGMII or else.

  • Hi Pubesh,

    I assigned IP to #define STATIC_IP_ADDRESS   0xC0A80A8C and cannot ping device (it is unreachable).

    I also use ARP Broadcast(0xFFFFFFFFFFFFh) to detect devices in the network and  lcdk6748 isn't on the list.

    When doing so I get packets with wrong MAC addresses in ethernet_input function (destination=0,src = MAC from some other device in the network).

    I wrote this function for loopback test:

    void SendTestPacket(void)
    {
        int x[]  = {0,1,2,3,4,5,6,7,8,9,10};
        Lan8710aLoopBackEnable(MDIO_0_BASE,7);
        struct pbuf* p;
        p = pbuf_alloc(PBUF_LINK,1024,PBUF_POOL);
        p->payload = &x;
        sitaraif_output(&sitaraNetIF[0],p);
    }

    It is called just  before while(1) loop in main but it doesn't trigger any RX core interrupt .

    Every MDIO command exectutes properly so I read  PHY's : linkstatus , partner ability, etc. Values are the same as in lan8710 datasheet.

    I guess I must be in MII mode because of: EMACMIIEnable(sitaraif->emac_base) .

    If you know any problems with porting am1808 lwip example to lcdk6748 just let me know.

    Best regards,

    Marcin Nowicki

  • Marcin,

    I understand that from your reply, the assigned IP is 192.168.10.140 (STATIC_IP_ADDRESS).
    Did you assign the MAC address(MAC_Addr)?
    I have seen your code LwIP_Init(), no MAC.
    I can suggest you, kindly run the StarterWare examples for Ethernet on LCDK6748 and understand the code.
    C6748_StarterWare_1_20_03_03\build\c674x\cgt_ccs\c6748\lcdkC6748\enet_echo
    C6748_StarterWare_1_20_03_03\build\c674x\cgt_ccs\c6748\lcdkC6748\enet_lwip

    And also some more examples available in NSP as the below path,
    nsp_1_10_00_03\packages\ti\ndk\examples

    You can take as a reference and migrate to LCDKC6748.

  • Im really sorry for misunderstanding,  I would like to inform you that I have been using code from C6748_StarterWare_1_20_03_03\build\c674x\cgt_ccs\c6748\lcdkC6748\enet_lwip since my second post.  (Code from my first post doesn't  matter)

    All MAC Initialization happens in lwIPInit->netif_add->sitaraif_init->sitaraif_hw_init(). This is where MAC addr is being set, phy initialized. The problem remains the same. I receive packets with wrong hardware addresses or completely empty packets. I think they are corrupted but can't find the cause.

    Best regards,

    Marcin

  • I finally solved the problem. The MAC module initialized wrong because the processor was booting from NAND flash.

    I recommend everyone to erase flash  before launching apps through JTAG otherwise this may cause unexpected potential problems.

    Anyway, thank you for feedback Pubesh.

    Best regards,

    Marcin

  • Marcin Nowicki,

    Finally found the root cause of this issue. I hope, this tread will be help to someone in future.