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.

the NDK driver for C6747

I want to modify ndk driver for my device,but I my driver stop at ’‘ i = EMAC_open( 1, (Handle)0x12345678, &ecfg, &hEMAC )’‘ in’‘ ethdriver.c’‘,

and the function   EMAC_open it does not run at all,what wrong with it?

I  am using

 bios_6_35_01_29

 xdctools_3_25_00_48

ndk_2_22_03_20

nsp_1_10_02_09

8738.csl_emac.c

7725.ethdriver.c
/**
 *   @file  ethdriver.c
 *
 *   @brief
 *       Ethernet Packet Driver written using the CSL and NIMU
 *		 Packet Architecture guidelines.
 *
 *  \par
 *  NOTE:
 *      (C) Copyright 2008, Texas Instruments, Inc.
 *
 *  \par
 */

#include <stdio.h>
#include <string.h>

#include <xdc/std.h>

#include <stkmain.h>

#include <emac_common.h>
#include <nimu_eth.h>
#include <csl_emac.h>
#include <csl_emacAux.h>

/**********************************************************************
 ****************** Global Variables / Definitions ********************
 **********************************************************************/

/* use compiler(-specific) intrinsics */
#define disableInterrupts() _disable_interrupts()
#define restoreInterrupts(key) _restore_interrupts(key)


#define     PKT_MAX                     64

#if defined(__TMS470__)
#define CORENUM 0
#define RXINT   34
#define TXINT   35
/*! TODO: review for ARM */
#define EXTERNAL_MEMORY             1
#define EXTMEM                      0x80000000
#else
#define CORENUM 1
#define RXINT   5
#define TXINT   6
#define EXTERNAL_MEMORY             1
#define EXTMEM                      0x80000000
#endif

static Handle hEMAC = 0;          /* Handle to our EMAC instance */
static PDINFO *pPDI = 0;          /* Handle to Device Info */
static Handle hMDIO = 0;          /* Handle to MDIO instance */
static Uint32 csl_errors = 0;     /* CSL returned error due to software */
static Uint32 emac_fatal_error = 0;    /* EMAC fatal error */
static Uint32 coreNum = CORENUM;
static Uint32 PktMTU;
static UINT8  bMacAddr[6] = {0x0, 0x11, 0x22, 0x33, 0x44, 0x55};
static Uint32 FlashActiveLED = 0;

/* Array of initialized EMAC packet buffers to handle incoming packets */
static EMAC_Pkt    rcv_pkt[PKT_MAX];

/* Array of EMAC packet placeholders to handle tx packets */
static EMAC_Pkt    send_pkt[PKT_MAX];

int         memory_squeeze_error = 0;

/**
 *
 * Configuration (Obtained via callback)
 *
 */
/* ideally we want to add one more param to getConfig, indicating mii/rmii phy mode,
 * so that we can dynamically configure as necessary at init time 
 * instead rebuilding the library
 */
extern void     EMAC_initialize(void);
extern void     EMAC_getConfig( UINT8 *pMacAddr );
extern void     EMAC_linkStatus( uint phy, uint linkStatus );

/**
 * @brief
 *  EMAC_Pkt Queue Data Structure
 *
 * @details
 *  Maintains the count of queued elements and head and tail to EMAC_Pkt queue.
 */
typedef struct pkt_queue {
    /**
     * @brief   Number of packets in queue
     */
    Uint32                Count;

    /**
     * @brief   Pointer to first packet
     */
    EMAC_Pkt          *pHead;

    /**
     * @brief   Pointer to last packet
     */
    EMAC_Pkt          *pTail;
} PKT_QUEUE;

static PKT_QUEUE     RxQueue;      /* Receive Queue */
static PKT_QUEUE     TxQueue;      /* Transmit Queue */

static EMAC_Pkt *Queue_pop( PKT_QUEUE *pq );
static void Queue_push( PKT_QUEUE *pq, EMAC_Pkt *pPktHdr );

static void Interrupt_init(void);
static void Interrupt_end(void);


/**********************************************************************
 *************************** EMAC Functions ***************************
 **********************************************************************/
/**
 *  @b Queue_pop
 *  @n
 *      Dequeues a packet from EMAC_Pkt queue.
 *
 *  @param[in]  pq
 *      Packet queue of type PKT_QUEUE .
 *
 *  @retval
 *      EMAC_Pkt popped from the queue.
 */
static EMAC_Pkt *Queue_pop( PKT_QUEUE *pq )
{
    EMAC_Pkt *pPktHdr = NULL;
    UInt key;

    key = disableInterrupts();

    pPktHdr = pq->pHead;

    if( pPktHdr ) 
    {
        pq->pHead = pPktHdr->pNext;
        pq->Count--;
        pPktHdr->pPrev = pPktHdr->pNext = 0;
    }

    restoreInterrupts(key);

    return( pPktHdr );
}


/**
 *  @b Queue_push
 *  @n
 *      Enqueues a packet in EMAC_Pkt queue.
 *
 *  @param[in]  pq
 *      Packet queue of type PKT_QUEUE .
 *  @param[in]  pPktHdr
 *      EMAC_Pkt type packet to push.
 *
 *  @retval
 *      void
 */
static void Queue_push( PKT_QUEUE *pq, EMAC_Pkt *pPktHdr )
{
    UInt key;

    key = disableInterrupts();

    pPktHdr->pNext = 0;

    if( !pq->pHead ) 
    {
        /* Queue is empty - Initialize it with this one packet */
        pq->pHead = pPktHdr;
        pq->pTail = pPktHdr;
    }
    else 
    {
        /* Queue is not empty - Push onto end */
        pq->pTail->pNext = pPktHdr;
        pq->pTail        = pPktHdr;
    }
    pq->Count++;

    restoreInterrupts(key);
}


/**
 *  @b GetPacket
 *  @n
 *      Returns a packet from the RxQueue.
 *
 *  @param[in]  hApplication
 *      Driver's handle.
 *
 *  @retval
 *		EMAC_Pkt pointer of a packet with buffer to replenish CSL.
 */
static EMAC_Pkt *GetPacket( Handle hApplication )
{
    EMAC_Pkt *pPkt = NULL;

    if( (Uint32)hApplication != 0x12345678 ) 
    {
        return NULL;
    }

    pPkt = Queue_pop(&RxQueue);

    if( pPkt ) 
	{
        pPkt->DataOffset = PBM_getDataOffset(pPkt->AppPrivate);
    }

#ifdef EXTERNAL_MEMORY
	/* Clean the cache for external addesses */
	if( (UINT32)(PBM_getDataBuffer(pPkt->AppPrivate)) & EXTMEM )
        OEMCacheClean( (void *)(PBM_getDataBuffer(pPkt->AppPrivate)), PBM_getBufferLen(pPkt->AppPrivate) );
#endif

    return( pPkt );
}

/**
 *  @b FreePacket
 *  @n
 *      Called by CSL to free the buffer.
 *
 *  @param[in]  hApplication
 *      Driver's handle.
 *  @param[in]  cslPkt
 *      EMAC_Pkt type packet passed by CSL.
 *
 *  @retval
 *      void
 */
static void FreePacket( Handle hApplication, EMAC_Pkt *cslPkt )
{
    if( (Uint32)hApplication != 0x12345678 )
    {
        return;
    }

    PBM_free( (PBM_Handle)cslPkt->AppPrivate );
    Queue_push( &TxQueue, cslPkt );
}

/**
 *  @b RxPacket
 *  @n
 *      Function called by CSL to pass the received packet to the driver.
 *
 *  @param[in]  hApplication
 *      Driver's handle.
 *  @param[in]  cslPkt
 *      EMAC_Pkt type packet passed by CSL.
 *
 *  @retval
 *		EMAC_Pkt pointer of a packet with buffer to replenish CSL.
 */
static EMAC_Pkt *RxPacket(Handle hApplication, EMAC_Pkt *cslPkt)
{
	PBM_Handle  hPkt;

	if( (Uint32)hApplication != 0x12345678 ) 
    {
	    return NULL;
    }

	hPkt = PBM_alloc(PktMTU + 4 + PKT_PREPAD);
	if (hPkt)
	{
		PBM_setValidLen((PBM_Handle) cslPkt->AppPrivate, cslPkt->ValidLen);
	    PBM_setIFRx((PBM_Handle) cslPkt->AppPrivate, pPDI->hEther );
	    PBMQ_enq( &pPDI->PBMQ_rx, (PBM_Handle) cslPkt->AppPrivate );

        /* Notify NDK stack of pending Rx Ethernet packet */
		STKEVENT_signal( pPDI->hEvent, STKEVENT_ETHERNET, 1 );

        PBM_setDataOffset( hPkt, PKT_PREPAD );
		cslPkt->AppPrivate  = (Uint32)hPkt;
		cslPkt->pDataBuffer = PBM_getDataBuffer(hPkt);
		cslPkt->BufferLen   = PBM_getBufferLen(hPkt);
		cslPkt->DataOffset = PBM_getDataOffset(hPkt);

#ifdef EXTERNAL_MEMORY
		/* Clean the cache for external addesses */
		 if( (UINT32)(PBM_getDataBuffer(cslPkt->AppPrivate)) & EXTMEM )
		   OEMCacheClean( (void *)(PBM_getDataBuffer(cslPkt->AppPrivate)), PBM_getBufferLen(cslPkt->AppPrivate) );
#endif
		return( cslPkt );
	}

	/* Increment the statistics to account for packets dropped because
	 * of memory squeeze 
     */
	memory_squeeze_error++;
	return cslPkt;
}

/**
 *  @b StatusUpdate
 *  @n
 *      Called from CSL on Rx/Tx MACFATAL error and from CSL timer tick function.
 *		Tells the driver of a status update.
 *
 *  @param[in]  hApplication
 *     Driver's Handle.
 *
 *  @retval
 *      void
 */
static void StatusUpdate( Handle hApplication )
{
    if( (Uint32)hApplication != 0x12345678 ) 
    {
        return;
    }

	emac_fatal_error++;
}

/**
 *  @b StatisticsUpdate
 *  @n
 *     Called by CSL to indicate a statistic update
 *     interrupt.
 *
 *  @param[in]  hApplication
 *     Driver's Handle.
 *
 *  @retval
 *      void
 */
static void StatisticsUpdate( Handle hApplication )
{
    if( (Uint32)hApplication != 0x12345678 ) 
    {
        return;
    }
}

/**
 *  @b HwPktInit
 *  @n
 *      Initializes the device MAC address to use. 
 *
 *  @param[in]  void
 *
 *  @retval
 *      Success -   1
 *  @retval
 *      Error   -   0
 */
uint HwPktInit()
{
    /* Get our EMAC address to use, overriding default initializer */
	EMAC_getConfig(bMacAddr);

    return (1);
}

/**
 *  @b HwPktShutdown
 *  @n
 *      Void
 *
 *  @param[in]  void
 *
 *  @retval
 *       void
 */
void HwPktShutdown()
{
}

/**
 *  @b HwPktOpen
 *  @n
 *      Opens and configures EMAC. Configures Interrupts, SGMII,
 *      and send and receive queues.
 *
 *  @param[in]  pi
 *      PDINFO structure pointer.
 *
 *  @retval
 *      Success -   0
 *  @retval
 *      Error   -   >0
 */
uint HwPktOpen( PDINFO *pi )
{
	Uint32          i, j;
    PBM_Handle      hPkt;
	EMAC_Config     ecfg;
	EMAC_AddrConfig *addrCfg;
    UInt key;

    pPDI = pi;

	ecfg.UseMdio            = 1;
	ecfg.CoreNum            = CORENUM;
	ecfg.PktMTU             = 1514;
	ecfg.TotalNumOfMacAddrs = 1;
	ecfg.DescBase           = EMAC_DESC_BASE_CPPI;

	PktMTU                  = ecfg.PktMTU;

	memset(&RxQueue, 0, sizeof(PKT_QUEUE));
    memset(&TxQueue, 0, sizeof(PKT_QUEUE));

    /* Queue up some initialized receive buffers */
	for( i=0; i<PKT_MAX; i++ )
	{
		hPkt = PBM_alloc(ecfg.PktMTU);
        /* Couldnt allocate memory, return error */
		if (hPkt == NULL)
			return 1;
		rcv_pkt[i].AppPrivate   = (Uint32)hPkt;
		rcv_pkt[i].pDataBuffer  = PBM_getDataBuffer(hPkt);
		rcv_pkt[i].BufferLen    = PBM_getBufferLen(hPkt);
        Queue_push( &RxQueue, &rcv_pkt[i] );
    }

    /* Queue up some transmit buffers */
	for( i=0; i<PKT_MAX; i++ )
	{
        Queue_push( &TxQueue, &send_pkt[i] );
    }

    ecfg.ModeFlags             = EMAC_CONFIG_MODEFLG_RXOFFLENBLOCK |
                                 EMAC_CONFIG_MODEFLG_RMII;
	ecfg.MdioModeFlags         = MDIO_MODEFLG_AUTONEG;

	/* channel usage must be mutual exclusive among cores */
	ecfg.ChannelInfo[0].RxChanEnable = 1;
	ecfg.ChannelInfo[0].TxChanEnable = 1;
	ecfg.ChannelInfo[1].RxChanEnable = 2;
	ecfg.ChannelInfo[1].TxChanEnable = 2;

    ecfg.RxMaxPktPool           = 8;
    ecfg.pfcbGetPacket          = &GetPacket;
    ecfg.pfcbFreePacket         = &FreePacket;
    ecfg.pfcbRxPacket           = &RxPacket;
    ecfg.pfcbStatus             = &StatusUpdate;
    ecfg.pfcbStatistics         = &StatisticsUpdate;

	/* allocate memory to two dimensional array to hold MAC addresses */
	ecfg.MacAddr = (EMAC_AddrConfig **)
     		       mmAlloc(ecfg.TotalNumOfMacAddrs * sizeof(EMAC_AddrConfig *));

	for ( j=0; j<ecfg.TotalNumOfMacAddrs; j++ )
    {
		ecfg.MacAddr[j] = (EMAC_AddrConfig *)mmAlloc(sizeof(EMAC_AddrConfig));
	}

//    /* Generate a default MAC address to use */
//    for( j=0; (Uint8)j<(ecfg.TotalNumOfMacAddrs); j++ )
//    {
//		addrCfg = ecfg.MacAddr[j];
//		addrCfg->ChannelNum = coreNum;
//		if( j>=3 && j<6 )
//			addrCfg->ChannelNum = 1;
//		if( j>=6 && j<9 )
//			addrCfg->ChannelNum = 2;
//   		for( i=0; i<6; i++ )
//        {
//		 	addrCfg->Addr[i] = j * 0x10 + i ;
//		}
//	}
//
//	addrCfg = ecfg.MacAddr[0];
//
//    /*  Check if EMAC_getConfig had returned a valid MAC address to use. If not,
//     *  use the default generated above.
//     */
//    for( i=0; (i<6) && (!(bMacAddr[i])); i++ );
//    if( i==6 )
//    {
//        mmCopy( (void *)&pPDI->bMacAddr[0], (void *)&addrCfg->Addr[0], 6 );
//		printf("Since EFUSE MAC address is Zero we use th MAC Address = %02x-%02x-%02x-%02x-%02x-%02x\n",
//               pPDI->bMacAddr[0],pPDI->bMacAddr[1],pPDI->bMacAddr[2],pPDI->bMacAddr[3],pPDI->bMacAddr[4],pPDI->bMacAddr[5]);
//    }
//    else
//    {
//        mmCopy( (void *)&addrCfg->Addr[0], (void *)&bMacAddr[0], 6 );
//    }
//
//	/* Copy the MAC Address into the PDI Structure */
//	mmCopy ((void *)&pPDI->bMacAddr[0], (void *)&addrCfg->Addr[0], 6);
//
//	addrCfg = ecfg.MacAddr[3 * coreNum + 2];

	//assinging MAC addresses
	for ( j=0; j<ecfg.TotalNumOfMacAddrs; j++ )
	{
		addrCfg = ecfg.MacAddr[j];
		addrCfg->ChannelNum = coreNum;
		memcpy((void *)&addrCfg->Addr[j], (void *)&bMacAddr[j], 6 );
		memcpy((void *)&pPDI->bMacAddr[j], (void *)&addrCfg->Addr[j], 6);
		printf("MAC Address = %02x-%02x-%02x-%02x-%02x-%02x\n",
			pPDI->bMacAddr[0], pPDI->bMacAddr[1], pPDI->bMacAddr[2],
			pPDI->bMacAddr[3], pPDI->bMacAddr[4], pPDI->bMacAddr[5]);
	}

    EMAC_initialize();

    key = disableInterrupts();
	printf("514 \n");
    i = EMAC_open( 1, (Handle)0x12345678, &ecfg, &hEMAC );
	printf("516 \n");
    if( i )
	{
        printf("EMAC OPEN Returned error \n");
		csl_errors++;
		return i;
	}
	printf("523 \n");
	Interrupt_init();
	printf("525 \n");
	hMDIO = ((EMAC_Device *)hEMAC)->hMDIO;

	/* Wait for link to come up */
    pi->TxFree = 0;

    /* Enable general purpose interrupt */
    restoreInterrupts(key);

    printf("EMAC should be up and running\n");

    return 0;
}

/**
 *  @b HwPktClose
 *  @n
 *      Closes EMAC and disables interrupts.
 *
 *  @param[in]  pi
 *      PDINFO structure pointer.
 *
 *  @retval
 *      void
 */
void HwPktClose( PDINFO *pi )
{
    EMAC_Pkt * p;
	Uint32 i;

    (void)pi;

	Interrupt_end();

    i = EMAC_close( hEMAC );

	if( i )
	{
		csl_errors++;
        printf("EMAC Close Returned error %08x\n",i);
    }

    while ((p = Queue_pop(&RxQueue)) != NULL) {
        if (p->AppPrivate) {
            PBM_free((PBM_Handle)p->AppPrivate);
        }
    }

    hEMAC = 0;
}

/**
 *  @b HwPktSetRx
 *  @n
 *      Sets the filter for EMAC. Also sets ram or hash multicast addresses.
 *
 *  @param[in]  pi
 *      PDINFO structure pointer.
 *
 *  @retval
 *      void
 */
void HwPktSetRx( PDINFO *pi )
{
    uint                tmp1,tmp2;
    int         i;
    Uint8       HashVal,tmpval,*pMCastList;
    UINT32      temp,temp1,MacHash1,MacHash2;
    UInt key;

	/* Clear the hash bits */
    MacHash1 = 0;
    MacHash2 = 0;

    if ( RAM_MCAST && (PKT_MAX_MCAST < 32) )        /* Use RAM based multicast list */
    {

        /* Clear the multicast list */
        for (i = 1; i < 32; i++)
        {
            EMAC_REGS->MACINDEX = i;
            EMAC_REGS->MACADDRHI = 0;
            EMAC_REGS->MACADDRLO = 0;
        }

        /* For each address in the list, add it to the RAM */
        pMCastList = pi->bMCast;
        for( tmp1=0; tmp1<pi->MCastCnt; tmp1++ )
        {
            EMAC_REGS->MACINDEX = tmp1+1;

            temp = 0;

            for( i=3; i>=0; i-- )
                    temp = (temp<<8) | *(pMCastList+i);
            EMAC_REGS->MACADDRHI = temp;

            temp = *(pMCastList+4);
            temp1 = *(pMCastList+5);
            EMAC_REGS->MACADDRLO = CSL_FMKT( EMAC_MACADDRLO_VALID, VALID ) |
                       CSL_FMKT( EMAC_MACADDRLO_MATCHFILT, MATCH ) |
                       CSL_FMK( EMAC_MACADDRLO_CHANNEL, 0 ) |
                       (temp1<<8) | temp ;
			pMCastList+=6;
        }
	}


    if ( HASH_MCAST )       /* Use hash tables multicast */
    {
        /* For each address in the list, hash and set the bit */
        pMCastList = pi->bMCast;
        for( tmp1=0; tmp1<pi->MCastCnt; tmp1++ )
        {
            HashVal=0;

            for( tmp2=0; tmp2<2; tmp2++ )
            {
                tmpval = *pMCastList++;
                HashVal ^= (tmpval>>2)^(tmpval<<4);
                tmpval = *pMCastList++;
                HashVal ^= (tmpval>>4)^(tmpval<<2);
                tmpval = *pMCastList++;
                HashVal ^= (tmpval>>6)^(tmpval);
            }

            if( HashVal & 0x20 )
                    MacHash2 |= (1<<(HashVal&0x1f));
            else
                    MacHash1 |= (1<<(HashVal&0x1f));
        }
	}

	((EMAC_Device *)hEMAC)->MacHash1 = MacHash1;
	((EMAC_Device *)hEMAC)->MacHash2 = MacHash2;

	key = disableInterrupts();
	i = EMAC_setReceiveFilter( hEMAC, pi->Filter, coreNum );
	restoreInterrupts(key);

    if( i )
	{
		csl_errors++;
        printf("EMAC_setReceiveFilter Returned error %08x\n",i);
		HwPktClose (pi);
	}

}

/**
 *  @b HwPktTxNext
 *  @n
 *      Routine to send out a packet.
 *
 *  @param[in]  pi
 *      PDINFO structure pointer.
 *
 *  @retval
 *      void
 */
void HwPktTxNext( PDINFO *pi )
{
#ifdef EXTERNAL_MEMORY
    register UINT8      *buffer;
    register uint       length;
#endif
    PBM_Handle          hPkt;
	EMAC_Pkt*		    csl_send_pkt;
	Uint32              i;
        UInt key;

    /* Checking for any queued packets to be transmitted */
    if( !(hPkt = PBMQ_deq(&pi->PBMQ_tx)) )
    {
        pi->TxFree = 1;
        return;
    }

#ifdef EXTERNAL_MEMORY
    buffer = PBM_getDataBuffer(hPkt) + PBM_getDataOffset(hPkt);
    length = PBM_getBufferLen(hPkt);


    /* Clean the cache for external addesses */
    if( (UINT32)buffer & EXTMEM )
        OEMCacheClean( (void *)buffer, length );
#endif

	csl_send_pkt = Queue_pop( &TxQueue );

	if( csl_send_pkt )
	{
		csl_send_pkt->AppPrivate 	= (Uint32)hPkt;
		csl_send_pkt->pDataBuffer	= PBM_getDataBuffer(hPkt);
	    csl_send_pkt->BufferLen  	= PBM_getBufferLen(hPkt);
	    csl_send_pkt->Flags      	= EMAC_PKT_FLAGS_SOP | EMAC_PKT_FLAGS_EOP;
	    csl_send_pkt->ValidLen   	= PBM_getValidLen(hPkt);
	    csl_send_pkt->DataOffset 	= PBM_getDataOffset(hPkt);
	    csl_send_pkt->PktChannel 	= coreNum; //0;
	    csl_send_pkt->PktLength  	= PBM_getValidLen(hPkt);
	    csl_send_pkt->PktFrags   	= 1;

		key = disableInterrupts();
		i = EMAC_sendPacket(hEMAC, csl_send_pkt);
		restoreInterrupts(key);

		if( i )
		{
			csl_errors++;
            printf("EMAC_sendPacket() returned error %08x\n",i);

			/* Free the packet as the packet did not go on the wire*/
			PBM_free( (PBM_Handle)csl_send_pkt->AppPrivate );

			Queue_push( &TxQueue, csl_send_pkt );
        }

		/* Packet has been transmitted */
		return;
	}

	/* Free the packet as the packet did not go on the wire. */
	PBM_free((PBM_Handle)hPkt);
	return;

}

/**
 *  @b _HwPktPoll
 *  @n
 *      This function is called at least every 100ms, faster in a
 *      polling environment. The fTimerTick flag is set only when
 *      called on a 100ms event.
 *
 *  @param[in]  pi
 *      PDINFO structure pointer.
 *  @param[in]  fTimerTick
 *      Flag for timer, set when called on a 100ms event.
 *
 *  @retval
 *      void
 */
void _HwPktPoll( PDINFO *pi, uint fTimerTick )
{
    uint mdioStatus,phy,linkStatus;
    UInt key;

    (void)pi;

    if( fTimerTick && hMDIO )
    {
        LED_TOGGLE( USER_LED2 );
        if(0u != FlashActiveLED )
        {
            FlashActiveLED = 0;
            LED_TOGGLE( USER_LED3 );
        }

        llEnter();
        key = disableInterrupts();

        /* Signal the MDIO */
        mdioStatus = MDIO_timerTick( hMDIO );

        /* Track new or lost link */
        if( mdioStatus == MDIO_EVENT_LINKDOWN || mdioStatus == MDIO_EVENT_LINKUP )
        {
            MDIO_getStatus( hMDIO, &phy, &linkStatus );

            /* On a new link, set the EMAC duplex */
            if( mdioStatus == MDIO_EVENT_LINKUP )
            {
                if( linkStatus == MDIO_LINKSTATUS_FD10 || linkStatus == MDIO_LINKSTATUS_FD100 )
                {
                    CSL_FINST( EMAC_REGS->MACCONTROL, EMAC_MACCONTROL_FULLDUPLEX, FULLDUPLEX );
                }
                else
                {
                    CSL_FINST( EMAC_REGS->MACCONTROL, EMAC_MACCONTROL_FULLDUPLEX, HALFDUPLEX );
                }

                /* Now that we have a link, send any queued packets */
                while( !pi->TxFree )
                    HwPktTxNext( pi );
            }
            /* Notify application of link status change */
            EMAC_linkStatus( phy, linkStatus );
        }
		else if ( mdioStatus == MDIO_EVENT_PHYERROR)
		{
			printf("NO PHY CONNECTED \n");
		}

        restoreInterrupts(key);
        llExit();
    }
}

/**
 *  @b HwRxInt
 *  @n
 *      Receive Packet ISR.
 *
 *  @param[in]  void
 *
 *  @retval
 *      void
 */
void HwRxInt(void * x)
{
	Uint32 i;

	if ( hEMAC )
    {
        i = EMAC_RxServiceCheck(hEMAC);

		if( i )
		{
			if (i == EMAC_ERROR_MACFATAL)
				emac_fatal_error++;
			else
				csl_errors++;
		}

        /* write the EOI register */
		EMAC_rxEoiWrite(coreNum);
    }

    return;
}

/**
 *  @b HwTxInt
 *  @n
 *      Transmit Complete ISR.
 *
 *  @param[in]  void
 *
 *  @retval
 *      void
 */
void HwTxInt(void * x)
{
	Uint32 i;

    if (hEMAC)
    {
        i = EMAC_TxServiceCheck(hEMAC);

		if(i)
		{
			if (i == EMAC_ERROR_MACFATAL)
				emac_fatal_error++;
			else
				csl_errors++;
		}

        /* write the EOI register */
		EMAC_txEoiWrite(coreNum);
    }

    return;
}


/**
 *  @b Interrupt_init
 *  @n
 *      Registering Interrupts and Enabling global interrupts.
 *
 *  @param[in]  void
 *
 *  @retval
 *      void
 */
static void Interrupt_init(void)
{
    IntSetup    hwi_intSetup;
    Uint32      retVal;

    /* Setup the Rx Int using NDK's Interrupt Manager */
    hwi_intSetup.intVectId = RXINT;
    hwi_intSetup.sysEvtCount = 1;
    hwi_intSetup.sysEvtId[0] = 31;
    hwi_intSetup.pCallbackFxn = &HwRxInt;
    hwi_intSetup.pCallbackArg = 0;
    hwi_intSetup.bEnable = 1;

    retVal = Interrupt_add(&hwi_intSetup);
    if(retVal != 0)
        printf("Error setting up Rx Interrupts \n");

    /* Setup the Tx Int using NDK's Interrupt Manager */
    hwi_intSetup.intVectId = TXINT;
    hwi_intSetup.sysEvtCount = 1;
    hwi_intSetup.sysEvtId[0] = 32;
    hwi_intSetup.pCallbackFxn = &HwTxInt;
    hwi_intSetup.pCallbackArg = 0;
    hwi_intSetup.bEnable = 1;

    retVal = Interrupt_add(&hwi_intSetup);
    if(retVal != 0)
        printf("Error setting up Tx Interrupts \n");

}


/**
 *  @b Interrupt_end
 *  @n
 *      Deregistering the interrupts
 *
 *  @param[in]  void
 *
 *  @retval
 *      void
 */
static void Interrupt_end(void)
{
    IntSetup intSetup;

    intSetup.intVectId = RXINT;
    Interrupt_delete(&intSetup);

    intSetup.intVectId = TXINT;
    Interrupt_delete(&intSetup);
}

  • Hello User,

    EMAC_open returns an error code on failure. What is error code (in this case value of i) you are receiving when driver stops?
    Also you need to configure correct values of speed, phy address etc.(also shown in comments of EMAC_open implementation) in the EMAC_Config structure which you are passing to EMAC_open().
    Can you share details of ecfg structure?

    Regards,
    Prasad
  • Hello India,

    I don't get any error code.it's comfusing.

    I want to modify the driver  for 6747 ,so i use printf() to confirm where is wrong.I add printf() after the  EMAC_open(),and I get nothing to reply.

    And I can't find what is the meaning of ecfg strucure .

    And I read

    .

    I found that I even don't need to word hard to  modify   ndk EMAC driver from omap138  C6748 to omap137 c6747..

    I can run the the program from Steven Connellon on omap-137  with the EMAC driver for omap-138 correctly. Is that true?

  • Hello,

    Are you saying EMAC_open never returns?
    I would suggest you to stepthrough using CCS and find where exactly it is hanging or returning error.

    About two posts you shared, i would wait Steve or Todd to comment on it as i don't have the knowledge about it.

    Regards,
    Prasad
  • user4627568 said:
    I want to modify the driver  for 6747 ,so i use printf() to confirm where is wrong.I add printf() after the  EMAC_open(),and I get nothing to reply.

    You have to be very careful when using printf(). In particular, you should not be using printf() calls in any ISR.  printf() halts the target in order to send data to from the target to the host PC (CCS), and when done at ISR level can cause undefined behavior.  Are you using printf() in any ISRs?

    I would recommend that you switch to using Log*_printf() instead of printf().  The Log module won't cause the target to halt like printf() does.

    See this page for details on Log APIs.

    Steve

  • user4627568 said:
    I can run the the program from Steven Connellon on omap-137  with the EMAC driver for omap-138 correctly. Is that true?

    Yes, you can try out the driver + application that I attached to the above thread that you found. Note (as also mentioned in the thread), that driver update was a quick pre-release port and was not fully tested (i.e. use at your own risk). But it should be enough to get you going.

  • Hello Steven

    Thank you very much.

  • No problem. If you feel your issue has been resolved, please mark this thread as "answered."

    Thanks,

    Steve
  • Hello,Steven
    And I am using the BSL.lib and evml137.c from you.
    I want know if I use my own circuit board with C6747,can i use the it? or what should I do if I want to modify BSL.lib to different PHY and what tools i need if i want to modify the BSL.lib ?
    I hope for your help.
  • If you plan to move your work over to custom hardware that use the 6747 chip, and a different EMAC, then you will be responsible for writing your own drivers.

    TI provides reference drivers for use with EVM boards, but we cannot support driver code for all of the permutations of custom hardware that folks may want to use.

    BSL was written by Spectrum Digital. I believe it was closed source, which may not help you much. You can find more information here: support.spectrumdigital.com/.../

    Steve